NexusForce 1.0.0
A rigorously engineered full-stack C++ backend library.
载入中...
搜索中...
未找到
reflect/function.hpp
浏览该文件的文档.
1#ifndef NEFORCE_CORE_REFLECT_FUNCTION_HPP__
2#define NEFORCE_CORE_REFLECT_FUNCTION_HPP__
3
10
14NEFORCE_BEGIN_NAMESPACE__
15NEFORCE_BEGIN_REFLECT__
16
22
30public:
31 using invoker = function<meta_any(void*, const vector<meta_any>&)>;
32
33private:
34 string_view name_;
35 invoker invoker_;
36 size_t min_args_ = 0;
37 size_t max_args_ = 0;
38
39public:
46 name_(name),
47 invoker_(move(invoker)) {}
48
53 NEFORCE_NODISCARD string_view name() const noexcept { return name_; }
54
61 meta_any invoke(void* obj, const vector<meta_any>& args) const {
62 if (!invoker_) {
63 return meta_any{};
64 }
65 try {
66 return invoker_(obj, args);
67 } catch (...) {
68 return meta_any{};
69 }
70 }
71
77 meta_any invoke(void* obj) const { return invoke(obj, {}); }
78
83 NEFORCE_NODISCARD size_t min_args() const { return min_args_; }
84
89 NEFORCE_NODISCARD size_t max_args() const { return max_args_; }
90
96 void set_arg_hints(size_t min, size_t max) {
97 min_args_ = min;
98 max_args_ = max;
99 }
100};
101 // Reflection
103
104NEFORCE_END_REFLECT__
105
106NEFORCE_BEGIN_INNER__
107
108template <typename Ret, typename Class, typename... Args, size_t... Is>
109Ret invoke_impl(Class* obj, Ret (Class::*func)(Args...), const vector<reflect::meta_any>& args,
110 index_sequence<Is...> /*unused*/) {
111 return (obj->*func)(args[Is].template convert<Args>()...);
112}
113
114template <typename Ret, typename Class, typename... Args, size_t... Is>
115Ret invoke_impl(const Class* obj, Ret (Class::*func)(Args...) const, const vector<reflect::meta_any>& args,
116 index_sequence<Is...> /*unused*/) {
117 return (obj->*func)(args[Is].template convert<Args>()...);
118}
119
120template <typename Ret, typename... Args, size_t... Is>
121Ret invoke_impl(Ret (*func)(Args...), const vector<reflect::meta_any>& args, index_sequence<Is...> /*unused*/) {
122 return (*func)(args[Is].template convert<Args>()...);
123}
124
125template <typename Ret, typename Class, typename... Args, enable_if_t<is_void_v<Ret>, int> = 0>
126decltype(auto) make_member_invoker(Ret (Class::*func)(Args...)) {
127 return [func](void* obj, const vector<reflect::meta_any>& args) -> reflect::meta_any {
128 if (sizeof...(Args) != args.size()) {
129 NEFORCE_THROW_EXCEPTION(value_exception("Argument count mismatch"));
130 }
131 inner::invoke_impl(static_cast<Class*>(obj), func, args, make_index_sequence<sizeof...(Args)>{});
132 return reflect::meta_any{};
133 };
134}
135
136template <typename Ret, typename Class, typename... Args, enable_if_t<!is_void_v<Ret>, int> = 0>
137decltype(auto) make_member_invoker(Ret (Class::*func)(Args...)) {
138 return [func](void* obj, const vector<reflect::meta_any>& args) -> reflect::meta_any {
139 if (sizeof...(Args) != args.size()) {
140 NEFORCE_THROW_EXCEPTION(value_exception("Argument count mismatch"));
141 }
142 auto result = inner::invoke_impl(static_cast<Class*>(obj), func, args, make_index_sequence<sizeof...(Args)>{});
143 return reflect::meta_any(result);
144 };
145}
146
147template <typename Ret, typename Class, typename... Args, enable_if_t<is_void_v<Ret>, int> = 0>
148decltype(auto) make_const_member_invoker(Ret (Class::*func)(Args...) const) {
149 return [func](void* obj, const vector<reflect::meta_any>& args) -> reflect::meta_any {
150 if (sizeof...(Args) != args.size()) {
151 NEFORCE_THROW_EXCEPTION(value_exception("Argument count mismatch"));
152 }
153 inner::invoke_impl(static_cast<const Class*>(obj), func, args, make_index_sequence<sizeof...(Args)>{});
154 return reflect::meta_any{};
155 };
156}
157
158template <typename Ret, typename Class, typename... Args, enable_if_t<!is_void_v<Ret>, int> = 0>
159decltype(auto) make_const_member_invoker(Ret (Class::*func)(Args...) const) {
160 return [func](void* obj, const vector<reflect::meta_any>& args) -> reflect::meta_any {
161 if (sizeof...(Args) != args.size()) {
162 NEFORCE_THROW_EXCEPTION(value_exception("Argument count mismatch"));
163 }
164 auto result =
165 inner::invoke_impl(static_cast<const Class*>(obj), func, args, make_index_sequence<sizeof...(Args)>{});
166 return reflect::meta_any(result);
167 };
168}
169
170template <typename Ret, typename... Args, enable_if_t<is_void_v<Ret>, int> = 0>
171decltype(auto) make_static_invoker(Ret (*func)(Args...)) {
172 return [func](void*, const vector<reflect::meta_any>& args) -> reflect::meta_any {
173 if (sizeof...(Args) != args.size()) {
174 NEFORCE_THROW_EXCEPTION(value_exception("Argument count mismatch"));
175 }
176 inner::invoke_impl(func, args, make_index_sequence<sizeof...(Args)>{});
177 return reflect::meta_any{};
178 };
179}
180
181template <typename Ret, typename... Args, enable_if_t<!is_void_v<Ret>, int> = 0>
182decltype(auto) make_static_invoker(Ret (*func)(Args...)) {
183 return [func](void*, const vector<reflect::meta_any>& args) -> reflect::meta_any {
184 if (sizeof...(Args) != args.size()) {
185 NEFORCE_THROW_EXCEPTION(value_exception("Argument count mismatch"));
186 }
187 auto result = inner::invoke_impl(func, args, make_index_sequence<sizeof...(Args)>{});
188 return reflect::meta_any(result);
189 };
190}
191
192NEFORCE_END_INNER__
193
194NEFORCE_END_NAMESPACE__
195#endif // NEFORCE_CORE_REFLECT_FUNCTION_HPP__
函数包装器主模板声明
string_view name() const noexcept
获取函数名称
size_t min_args() const
获取最小参数数量
function< meta_any(void *, const vector< meta_any > &)> invoker
函数调用器类型
meta_any invoke(void *obj, const vector< meta_any > &args) const
调用函数
size_t max_args() const
获取最大参数数量
meta_any invoke(void *obj) const
调用无参函数
meta_function(string_view name, invoker invoker)
构造函数
void set_arg_hints(size_t min, size_t max)
设置参数数量提示
动态大小数组容器
通用函数包装器
constexpr const T & min(const T &a, const T &b, Compare comp) noexcept(noexcept(comp(b, a)))
返回两个值中的较小者
constexpr const T & max(const T &a, const T &b, Compare comp) noexcept(noexcept(comp(a, b)))
返回两个值中的较大者
integer_sequence< size_t, Values... > index_sequence
索引序列
constexpr Iterator2 move(Iterator1 first, Iterator1 last, Iterator2 result) noexcept(noexcept(inner::__move_aux(first, last, result)))
移动范围元素
basic_string_view< char > string_view
字符字符串视图
类型擦除容器
动态大小数组容器