Fixes for VS2019 and C++17 compilation
1 |
#ifndef CHAISCRIPT_FUNCTION_SIGNATURE_HPP
|
|
2 |
#define CHAISCRIPT_FUNCTION_SIGNATURE_HPP
|
|
3 |
|
|
4 |
#include <type_traits> |
|
5 |
|
|
6 |
namespace chaiscript::dispatch::detail { |
|
7 |
|
|
8 |
template<typename... Param> |
|
9 |
struct Function_Params |
|
10 |
{
|
|
11 |
};
|
|
12 |
|
|
13 |
template<typename Ret, typename Params, bool IsNoExcept = false, bool IsMember = false, bool IsMemberObject = false, bool IsObject = false> |
|
14 |
struct Function_Signature |
|
15 |
{
|
|
16 |
using Param_Types = Params; |
|
17 |
using Return_Type = Ret; |
|
18 |
constexpr static const bool is_object = IsObject; |
|
19 |
constexpr static const bool is_member_object = IsMemberObject; |
|
20 |
constexpr static const bool is_noexcept = IsNoExcept; |
|
21 |
template<typename T> |
|
22 | 1 |
constexpr Function_Signature(T &&) noexcept {} |
23 |
constexpr Function_Signature() noexcept = default; |
|
24 |
};
|
|
25 |
|
|
26 |
// Free functions
|
|
27 |
|
|
28 |
template<typename Ret, typename... Param> |
|
29 |
Function_Signature(Ret (*f)(Param...))->Function_Signature<Ret, Function_Params<Param...>>; |
|
30 |
|
|
31 |
template<typename Ret, typename... Param> |
|
32 |
Function_Signature(Ret (*f)(Param...) noexcept)->Function_Signature<Ret, Function_Params<Param...>, true>; |
|
33 |
|
|
34 |
// no reference specifier
|
|
35 |
|
|
36 |
template<typename Ret, typename Class, typename... Param> |
|
37 |
Function_Signature(Ret (Class::*f)(Param...) volatile)->Function_Signature<Ret, Function_Params<volatile Class &, Param...>, false, true>; |
|
38 |
|
|
39 |
template<typename Ret, typename Class, typename... Param> |
|
40 |
Function_Signature(Ret (Class::*f)(Param...) volatile noexcept)->Function_Signature<Ret, Function_Params<volatile Class &, Param...>, true, true>; |
|
41 |
|
|
42 |
template<typename Ret, typename Class, typename... Param> |
|
43 |
Function_Signature(Ret (Class::*f)(Param...) volatile const)->Function_Signature<Ret, Function_Params<volatile const Class &, Param...>, false, true>; |
|
44 |
|
|
45 |
template<typename Ret, typename Class, typename... Param> |
|
46 |
Function_Signature(Ret (Class::*f)(Param...) volatile const noexcept)->Function_Signature<Ret, Function_Params<volatile const Class &, Param...>, true, true>; |
|
47 |
|
|
48 |
template<typename Ret, typename Class, typename... Param> |
|
49 |
Function_Signature(Ret (Class::*f)(Param...))->Function_Signature<Ret, Function_Params<Class &, Param...>, false, true>; |
|
50 |
|
|
51 |
template<typename Ret, typename Class, typename... Param> |
|
52 |
Function_Signature(Ret (Class::*f)(Param...) noexcept)->Function_Signature<Ret, Function_Params<Class &, Param...>, true, true>; |
|
53 |
|
|
54 |
template<typename Ret, typename Class, typename... Param> |
|
55 |
Function_Signature(Ret (Class::*f)(Param...) const)->Function_Signature<Ret, Function_Params<const Class &, Param...>, false, true>; |
|
56 |
|
|
57 |
template<typename Ret, typename Class, typename... Param> |
|
58 |
Function_Signature(Ret (Class::*f)(Param...) const noexcept)->Function_Signature<Ret, Function_Params<const Class &, Param...>, true, true>; |
|
59 |
|
|
60 |
// & reference specifier
|
|
61 |
|
|
62 |
template<typename Ret, typename Class, typename... Param> |
|
63 |
Function_Signature(Ret (Class::*f)(Param...) volatile &)->Function_Signature<Ret, Function_Params<volatile Class &, Param...>, false, true>; |
|
64 |
|
|
65 |
template<typename Ret, typename Class, typename... Param> |
|
66 |
Function_Signature(Ret (Class::*f)(Param...) volatile &noexcept)->Function_Signature<Ret, Function_Params<volatile Class &, Param...>, true, true>; |
|
67 |
|
|
68 |
template<typename Ret, typename Class, typename... Param> |
|
69 |
Function_Signature(Ret (Class::*f)(Param...) volatile const &)->Function_Signature<Ret, Function_Params<volatile const Class &, Param...>, false, true>; |
|
70 |
|
|
71 |
template<typename Ret, typename Class, typename... Param> |
|
72 |
Function_Signature(Ret (Class::*f)(Param...) volatile const &noexcept)->Function_Signature<Ret, Function_Params<volatile const Class &, Param...>, true, true>; |
|
73 |
|
|
74 |
template<typename Ret, typename Class, typename... Param> |
|
75 |
Function_Signature(Ret (Class::*f)(Param...) &)->Function_Signature<Ret, Function_Params<Class &, Param...>, false, true>; |
|
76 |
|
|
77 |
template<typename Ret, typename Class, typename... Param> |
|
78 |
Function_Signature(Ret (Class::*f)(Param...) & noexcept)->Function_Signature<Ret, Function_Params<Class &, Param...>, true, true>; |
|
79 |
|
|
80 |
template<typename Ret, typename Class, typename... Param> |
|
81 |
Function_Signature(Ret (Class::*f)(Param...) const &)->Function_Signature<Ret, Function_Params<const Class &, Param...>, false, true>; |
|
82 |
|
|
83 |
template<typename Ret, typename Class, typename... Param> |
|
84 |
Function_Signature(Ret (Class::*f)(Param...) const &noexcept)->Function_Signature<Ret, Function_Params<const Class &, Param...>, true, true>; |
|
85 |
|
|
86 |
// && reference specifier
|
|
87 |
|
|
88 |
template<typename Ret, typename Class, typename... Param> |
|
89 |
Function_Signature(Ret (Class::*f)(Param...) volatile &&)->Function_Signature<Ret, Function_Params<volatile Class &&, Param...>, false, true>; |
|
90 |
|
|
91 |
template<typename Ret, typename Class, typename... Param> |
|
92 |
Function_Signature(Ret (Class::*f)(Param...) volatile &&noexcept)->Function_Signature<Ret, Function_Params<volatile Class &&, Param...>, true, true>; |
|
93 |
|
|
94 |
template<typename Ret, typename Class, typename... Param> |
|
95 |
Function_Signature(Ret (Class::*f)(Param...) volatile const &&)->Function_Signature<Ret, Function_Params<volatile const Class &&, Param...>, false, true>; |
|
96 |
|
|
97 |
template<typename Ret, typename Class, typename... Param> |
|
98 |
Function_Signature(Ret (Class::*f)(Param...) volatile const &&noexcept)->Function_Signature<Ret, Function_Params<volatile const Class &&, Param...>, true, true>; |
|
99 |
|
|
100 |
template<typename Ret, typename Class, typename... Param> |
|
101 |
Function_Signature(Ret (Class::*f)(Param...) &&)->Function_Signature<Ret, Function_Params<Class &&, Param...>, false, true>; |
|
102 |
|
|
103 |
template<typename Ret, typename Class, typename... Param> |
|
104 |
Function_Signature(Ret (Class::*f)(Param...) && noexcept)->Function_Signature<Ret, Function_Params<Class &&, Param...>, true, true>; |
|
105 |
|
|
106 |
template<typename Ret, typename Class, typename... Param> |
|
107 |
Function_Signature(Ret (Class::*f)(Param...) const &&)->Function_Signature<Ret, Function_Params<const Class &&, Param...>, false, true>; |
|
108 |
|
|
109 |
template<typename Ret, typename Class, typename... Param> |
|
110 |
Function_Signature(Ret (Class::*f)(Param...) const &&noexcept)->Function_Signature<Ret, Function_Params<const Class &&, Param...>, true, true>; |
|
111 |
|
|
112 |
template<typename Ret, typename Class> |
|
113 |
Function_Signature(Ret(Class::*f))->Function_Signature<Ret, Function_Params<Class &>, true, true, true>; |
|
114 |
|
|
115 |
// primary template handles types that have no nested ::type member:
|
|
116 |
template<class, class = std::void_t<>> |
|
117 |
struct has_call_operator : std::false_type |
|
118 |
{
|
|
119 |
};
|
|
120 |
|
|
121 |
// specialization recognizes types that do have a nested ::type member:
|
|
122 |
template<class T> |
|
123 |
struct has_call_operator<T, std::void_t<decltype(&T::operator())>> : std::true_type |
|
124 |
{
|
|
125 |
};
|
|
126 |
|
|
127 |
template<typename Func> |
|
128 | 1 |
auto function_signature(const Func &f) |
129 |
{
|
|
130 |
if constexpr (has_call_operator<Func>::value) { |
|
131 |
return Function_Signature< |
|
132 |
typename decltype(Function_Signature{ &std::decay_t<Func>::operator() })::Return_Type, |
|
133 |
typename decltype(Function_Signature{ &std::decay_t<Func>::operator() })::Param_Types, |
|
134 |
decltype(Function_Signature{ &std::decay_t<Func>::operator() })::is_noexcept, |
|
135 |
false, |
|
136 |
false, |
|
137 | 1 |
true>{}; |
138 |
} else { |
|
139 | 1 |
return Function_Signature{ f }; |
140 |
}
|
|
141 |
}
|
|
142 |
|
|
143 |
}// namespace chaiscript::dispatch::detail |
|
144 |
|
|
145 |
#endif
|
Read our documentation on viewing source code .