ChaiScript / ChaiScript
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 .

Loading