NIM 跨平台 C++ SDK
载入中...
搜索中...
未找到
ne_stl_bind.h
浏览该文件的文档.
1#ifndef NE_STL_INCLUDENE_STL_BIND_H
2#define NE_STL_INCLUDENE_STL_BIND_H
3
4#include "ne_stl_atomic.h"
5#include "ne_stl_build.h"
6#include "ne_stl_memory.h"
7#include "ne_stl_smart_ptr.h"
8#include "ne_stl_tuple.h"
9
10namespace nstd {
11typedef struct _weak_flag {
20
21template <typename T>
22struct type {
23 using value = T;
24};
25template <typename R>
27 using type = R;
28};
29template <typename F>
30struct result_traits<type<F>> : result_traits<typename F::result_type> {};
32template <int32_t index>
46 template <typename... TArgs>
47 static int32_t count(const nstd::tuple<TArgs...>&) {
48 int32_t count = 0;
49 get_i<sizeof...(TArgs), TArgs...>(count);
50 return count;
51 }
52 template <int32_t I, typename T, typename... TArgs>
53 static void get_i(int32_t& count) {
54 if (!std::is_base_of<argc_placeholders_base, T>::value) {
55 count += 1;
56 get_i<sizeof...(TArgs), TArgs...>(count);
57 }
58 }
59 template <int32_t I>
60 static void get_i(int32_t& count) {}
61};
62template <typename TR, typename TC, typename TF, typename TCaptured>
63struct bind_t {
64 template <typename R, typename C, typename... TArgs, typename TUP, int32_t... Index_1, typename TUP2, int32_t... Index_2>
65 static R bind_t_call_(R (C::*f)(TArgs...),
66 C* obj,
67 const TUP& tup,
68 nstd::int_sequence<Index_1...>,
69 const TUP2& tup2,
70 nstd::int_sequence<Index_2...>) {
71 return (obj->*f)(nstd::tuple_get<Index_1>(tup)..., nstd::tuple_get<Index_2>(tup2)...);
72 }
73 template <typename R, typename C, typename... TArgs, typename... Ts_1, typename... Ts_2>
74 static R bind_t_call(R (C::*f)(TArgs...), C* obj, const nstd::tuple<Ts_1...>& tup, const nstd::tuple<Ts_2...>& tup2) {
75 return bind_t_call_(f, obj, tup, nstd::sequence_t<sizeof...(Ts_1)>{}, tup2, nstd::sequence_t<sizeof...(Ts_2)>{});
76 }
77 template <typename R, typename C, typename... TArgs, typename TUP, int32_t... Index_1, typename TUP2, int32_t... Index_2>
78 static R bind_t_call_(R (C::*f)(TArgs...) const,
79 C* obj,
80 const TUP& tup,
81 nstd::int_sequence<Index_1...>,
82 const TUP2& tup2,
83 nstd::int_sequence<Index_2...>) {
84 return (obj->*f)(nstd::tuple_get<Index_1>(tup)..., nstd::tuple_get<Index_2>(tup2)...);
85 }
86 template <typename R, typename C, typename... TArgs, typename... Ts_1, typename... Ts_2>
87 static R bind_t_call(R (C::*f)(TArgs...) const, C* obj, const nstd::tuple<Ts_1...>& tup, const nstd::tuple<Ts_2...>& tup2) {
88 return bind_t_call_(f, obj, tup, nstd::sequence_t<sizeof...(Ts_1)>{}, tup2, nstd::sequence_t<sizeof...(Ts_2)>{});
89 }
90 bind_t(TF f, TC* obj, const TCaptured& params, const nstd::weak_ptr<nstd::weak_flag>& weak_flag)
91 : obj_(obj)
92 , functor_(f)
94 , captured_params_(params) {}
95 template <typename... TParams>
96 inline TR operator()(TParams... params) {
97 if (weak_flag_.expired())
98 return TR();
99 if constexpr (sizeof...(params) > 0) {
101 } else {
103 }
104 }
105 template <typename... TParams>
106 inline TR operator()(TParams... params) const {
107 if (weak_flag_.expired())
108 return TR();
109 if constexpr (sizeof...(params) > 0) {
111 } else {
113 }
114 }
115 TC* obj_;
119};
120template <typename R, typename C, typename... Args, typename... Params>
121bind_t<R, C, R (C::*)(Args...), nstd::tuple<Params...>> bind(R (C::*f)(Args...), C* obj, Params... params) {
122 static_assert(std::is_base_of<nstd::weak_semantics_supporter, C>::value, "nstd::_weak_semantics_supporter should be base of C");
123 return bind_t<R, C, R (C::*)(Args...), nstd::tuple<Params...>>(f, obj, nstd::make_tuple(params...), obj->get_weak_flag());
124}
125template <typename R, typename C, typename... Args, typename... Params>
126bind_t<R, C, R (C::*)(Args...) const, nstd::tuple<Params...>> bind(R (C::*f)(Args...) const, C* obj, Params... params) {
127 static_assert(std::is_base_of<nstd::weak_semantics_supporter, C>::value, "nstd::_weak_semantics_supporter should be base of C");
128 return bind_t<R, C, R (C::*)(Args...) const, nstd::tuple<Params...>>(f, obj, nstd::make_tuple(params...), obj->get_weak_flag());
129}
130
131template <typename T>
132struct function;
133template <typename R, typename... Args>
134struct function<R(Args...)> {
135private:
136 template <typename T>
137 struct _function;
138 template <typename _R, typename... _Args>
139 struct _function<_R(_Args...)> {
141 using invoke_fn_t = _R (*)(char*, _Args...);
142 using construct_fn_t = void (*)(char*, char*);
143 using destroy_fn_t = void (*)(char*);
144 template <typename Functor>
145 static result_type invoke_fn(Functor* fn, _Args... args) {
146 return (*fn)(args...);
147 }
148 template <typename Functor>
149 static void construct_fn(Functor* construct_dst, Functor* construct_src) {
150 new (construct_dst) Functor(*construct_src);
151 }
152 template <typename Functor>
153 static void destroy_fn(Functor*& f) {
154 if (f != nullptr) {
155 f->~Functor();
156 memory::safe_delete_container_element(reinterpret_cast<char*&>(f));
157 }
158 }
160
161 public:
163 : invoke_f(nullptr)
164 , construct_f(nullptr)
165 , data_ptr(nullptr)
166 , data_size(0) {}
167 _function(std::nullptr_t)
168 : invoke_f(nullptr)
169 , construct_f(nullptr)
170 , data_ptr(nullptr)
171 , data_size(0) {}
172 template <typename Functor>
173 _function(const Functor& f)
174 : invoke_f(reinterpret_cast<invoke_fn_t>(invoke_fn<Functor>))
175 , construct_f(reinterpret_cast<construct_fn_t>(construct_fn<Functor>))
176 , data_size(sizeof(Functor)) {
177 this->data_ptr = nstd::make_shared<vector<char>>();
178 this->data_ptr->set_element_delete_function(reinterpret_cast<nstd::element_delete_fun_t<char>>(destroy_fn<Functor>));
179 this->data_ptr->resize(data_size);
180 this->construct_f((char*)this->data_ptr->data(), reinterpret_cast<char*>(const_cast<Functor*>(&f)));
181 }
182 _function(const _function& rhs)
183 : invoke_f(rhs.invoke_f)
184 , construct_f(rhs.construct_f)
185 , data_ptr(rhs.data_ptr)
186 , data_size(rhs.data_size) {}
187 _function& operator=(const _function& rhs) {
188 this->invoke_f = rhs.invoke_f;
189 this->construct_f = rhs.construct_f;
190 this->data_size = rhs.data_size;
191 this->data_ptr = rhs.data_ptr;
192 return *this;
193 }
194 template <typename Functor>
195 _function& operator=(const Functor& f) {
196 this->invoke_f = reinterpret_cast<invoke_fn_t>(invoke_fn<Functor>);
197 this->construct_f = reinterpret_cast<construct_fn_t>(construct_fn<Functor>);
198 this->data_size = sizeof(Functor);
199 this->data_ptr = nstd::make_shared<vector<char>>();
200 this->data_ptr->set_element_delete_function(reinterpret_cast<nstd::element_delete_fun_t<char>>(destroy_fn<Functor>));
201 this->data_ptr->resize(data_size);
202 this->construct_f((char*)this->data_ptr->data(), reinterpret_cast<char*>(const_cast<Functor*>(&f)));
203 return *this;
204 }
205 _function& operator=(std::nullptr_t) {
206 this->invoke_f = nullptr;
207 this->construct_f = nullptr;
208 this->data_ptr = nullptr;
209 this->data_size = 0;
210 return *this;
211 }
213 inline bool operator==(std::nullptr_t) const { return !this->operator bool(); }
214 inline bool operator!=(std::nullptr_t) const { return this->operator bool(); }
215 inline bool operator==(const _function& other) const { return this->data_ptr == other.data_ptr; }
216 inline bool operator!=(const _function& other) const { return !this->operator==(other); }
217 inline operator bool() const { return this->data_ptr != nullptr; }
218 _R operator()(_Args... args) {
219 if (this->data_ptr.get() != nullptr)
220 return this->invoke_f((char*)this->data_ptr.get()->data(), args...);
221 else {
222 assert(false);
223 return _R();
224 }
225 }
226 _R operator()(_Args... args) const {
227 if (this->data_ptr != nullptr)
228 return this->invoke_f((char*)this->data_ptr.get()->data(), args...);
229 else {
230 assert(false);
231 return _R();
232 }
233 }
237 std::size_t data_size;
238 };
239
240private:
241 using deref_notify_t = _function<void()>;
242 struct _ref_flag {
243 _ref_flag(const deref_notify_t& _deref_notify)
244 : deref_notify(_deref_notify) {}
246 if (deref_notify != nullptr)
247 deref_notify();
248 }
250 };
252
253public:
254 function() { static_assert(nstd::is_all_standard_layout<Args...>::value, "Args should standard layout"); }
255 function(std::nullptr_t) { static_assert(nstd::is_all_standard_layout<Args...>::value, "Args should standard layout"); }
256 template <typename Functor>
257 function(const Functor& f, const deref_notify_t& deref_notify = nullptr)
258 : __function_(f)
259 , __ref_flag_(nstd::make_shared<_ref_flag>(deref_notify)) {
260 static_assert(nstd::is_all_standard_layout<Args...>::value, "Args should standard layout");
261 }
262 function(const function& rhs)
263 : __function_(rhs.__function_)
264 , __ref_flag_(rhs.__ref_flag_) {
265 static_assert(nstd::is_all_standard_layout<Args...>::value, "Args should standard layout");
266 }
268 this->__function_ = rhs.__function_;
269 this->__ref_flag_ = rhs.__ref_flag_;
270 return *this;
271 }
272 template <typename Functor>
273 function& operator=(const Functor& f) {
274 this->__function_ = f;
275 this->__ref_flag_ = nullptr;
276 return *this;
277 }
278 function& operator=(std::nullptr_t) {
279 this->__function_ = nullptr;
280 this->__ref_flag_ = nullptr;
281 return *this;
282 }
283 ~function() { __ref_flag_.reset(); }
284 inline bool operator==(std::nullptr_t) const { return !this->operator bool(); }
285 inline bool operator!=(std::nullptr_t) const { return this->operator bool(); }
286 inline bool operator==(const function& other) const { return this->__function_ == other.__function_; }
287 inline bool operator!=(const function& other) const { return !this->operator==(other); }
288 inline operator bool() const { return this->__function_ != nullptr; }
289 R operator()(Args... args) {
290 if (this->__function_ != nullptr)
291 return this->__function_(args...);
292 else {
293 assert(false);
294 return R();
295 }
296 }
297 R operator()(Args... args) const {
298 if (this->__function_ != nullptr)
299 return this->__function_.operator()(args...);
300 else {
301 assert(false);
302 return R();
303 }
304 }
305
306private:
307 _function<R(Args...)> __function_{nullptr};
308 ref_flag_t __ref_flag_{nullptr};
309};
310
311namespace {
312namespace traits {
313template <class T>
314struct _is_std_function;
315}
316namespace detail {
317template <typename... TArgs>
318struct _Has_std_function;
319class _Is_std_function {
320 template <class TCheck>
321 friend struct traits::_is_std_function;
322 template <typename... TArgs>
323 friend struct _Has_std_function;
324 template <class T>
325 static constexpr bool _v() {
326 return _v((T*)(nullptr));
327 }
328 template <class TR, class... Args>
329 static constexpr bool _v(nstd::function<TR(Args...)>* p) {
330 return true;
331 }
332 template <class T>
333 static constexpr bool _v(T* p) {
334 return false;
335 }
336};
337template <typename... TArgs>
338struct _Has_std_function {};
339template <>
340struct _Has_std_function<> : nstd::false_type {};
341template <typename T, typename... TArgs>
342struct _Has_std_function<T, TArgs...>
343 : nstd::conditional<_Is_std_function::_v<typename nstd::remove_cr<T>::type>(), nstd::true_type, _Has_std_function<TArgs...>>::type {};
344} // namespace detail
345namespace traits {
346template <class T>
347struct _is_std_function
348 : public nstd::conditional<detail::_Is_std_function::_v<typename nstd::remove_cr<T>::type>(), nstd::true_type, nstd::false_type>::type {};
349
350template <class... T>
351using _has_std_function = detail::_Has_std_function<T...>;
352} // namespace traits
353} // namespace
354
355template <class T>
356using is_std_function = traits::_is_std_function<T>;
357template <class... T>
358using has_std_function = traits::_has_std_function<T...>;
359
360} // namespace nstd
361
362#endif // !NE_STL_INCLUDENE_STL_BIND_H
Definition ne_stl_continuous_container.h:15
Definition ne_stl_smart_ptr.h:30
Definition ne_stl_smart_ptr.h:146
static _argc_placeholder< 7 > _7
Definition ne_stl_bind.h:41
static _argc_placeholder< 8 > _8
Definition ne_stl_bind.h:42
static _argc_placeholder< 5 > _5
Definition ne_stl_bind.h:39
static _argc_placeholder< 9 > _9
Definition ne_stl_bind.h:43
static _argc_placeholder< 6 > _6
Definition ne_stl_bind.h:40
static _argc_placeholder< 3 > _3
Definition ne_stl_bind.h:37
static _argc_placeholder< 1 > _1
Definition ne_stl_bind.h:35
static _argc_placeholder< 4 > _4
Definition ne_stl_bind.h:38
static _argc_placeholder< 2 > _2
Definition ne_stl_bind.h:36
Definition ne_stl_any.h:7
traits::_is_std_function< T > is_std_function
Definition ne_stl_bind.h:356
bind_t< R, C, R(C::*)(Args...), nstd::tuple< Params... > > bind(R(C::*f)(Args...), C *obj, Params... params)
Definition ne_stl_bind.h:121
traits::_is_all_standard_layout< T... > is_all_standard_layout
Definition ne_stl_type_traits.h:86
struct nstd::_weak_semantics_supporter weak_semantics_supporter
typename int_sequence_gen< N >::type sequence_t
Definition ne_stl_tuple.h:24
void(*)(TElement *&) element_delete_fun_t
Definition ne_stl_memory.h:13
nstd::shared_ptr< T > make_shared(TArgs &&... args)
Definition ne_stl_smart_ptr.h:209
traits::_has_std_function< T... > has_std_function
Definition ne_stl_bind.h:358
struct nstd::_weak_flag weak_flag
tuple< Type... > make_tuple(const Type &... args)
Definition ne_stl_tuple.h:66
unsigned char bool
Definition stdbool.h:25
Definition ne_stl_bind.h:33
Definition ne_stl_type_traits.h:9
Definition ne_stl_bind.h:11
Definition ne_stl_bind.h:13
nstd::weak_ptr< nstd::weak_flag > get_weak_flag()
Definition ne_stl_bind.h:15
_weak_semantics_supporter()
Definition ne_stl_bind.h:14
nstd::shared_ptr< nstd::weak_flag > shared_obj_
Definition ne_stl_bind.h:18
Definition ne_stl_bind.h:31
Definition ne_stl_bind.h:63
bind_t(TF f, TC *obj, const TCaptured &params, const nstd::weak_ptr< nstd::weak_flag > &weak_flag)
Definition ne_stl_bind.h:90
TR operator()(TParams... params)
Definition ne_stl_bind.h:96
static R bind_t_call_(R(C::*f)(TArgs...) const, C *obj, const TUP &tup, nstd::int_sequence< Index_1... >, const TUP2 &tup2, nstd::int_sequence< Index_2... >)
Definition ne_stl_bind.h:78
TR operator()(TParams... params) const
Definition ne_stl_bind.h:106
static R bind_t_call_(R(C::*f)(TArgs...), C *obj, const TUP &tup, nstd::int_sequence< Index_1... >, const TUP2 &tup2, nstd::int_sequence< Index_2... >)
Definition ne_stl_bind.h:65
TF functor_
Definition ne_stl_bind.h:116
TCaptured captured_params_
Definition ne_stl_bind.h:118
TC * obj_
Definition ne_stl_bind.h:115
nstd::weak_ptr< nstd::weak_flag > weak_flag_
Definition ne_stl_bind.h:117
static R bind_t_call(R(C::*f)(TArgs...), C *obj, const nstd::tuple< Ts_1... > &tup, const nstd::tuple< Ts_2... > &tup2)
Definition ne_stl_bind.h:74
static R bind_t_call(R(C::*f)(TArgs...) const, C *obj, const nstd::tuple< Ts_1... > &tup, const nstd::tuple< Ts_2... > &tup2)
Definition ne_stl_bind.h:87
Definition ne_stl_type_traits.h:33
bool operator==(const _function &other) const
Definition ne_stl_bind.h:215
_function & operator=(std::nullptr_t)
Definition ne_stl_bind.h:205
typename result_traits< _R >::type result_type
Definition ne_stl_bind.h:140
invoke_fn_t invoke_f
Definition ne_stl_bind.h:234
void(*)(char *) destroy_fn_t
Definition ne_stl_bind.h:143
_function(const _function &rhs)
Definition ne_stl_bind.h:182
bool operator!=(const _function &other) const
Definition ne_stl_bind.h:216
static void construct_fn(Functor *construct_dst, Functor *construct_src)
Definition ne_stl_bind.h:149
static result_type invoke_fn(Functor *fn, _Args... args)
Definition ne_stl_bind.h:145
void(*)(char *, char *) construct_fn_t
Definition ne_stl_bind.h:142
_R operator()(_Args... args)
Definition ne_stl_bind.h:218
_R operator()(_Args... args) const
Definition ne_stl_bind.h:226
std::size_t data_size
Definition ne_stl_bind.h:237
_function & operator=(const _function &rhs)
Definition ne_stl_bind.h:187
_function(std::nullptr_t)
Definition ne_stl_bind.h:167
bool operator!=(std::nullptr_t) const
Definition ne_stl_bind.h:214
_R(*)(char *, _Args...) invoke_fn_t
Definition ne_stl_bind.h:141
bool operator==(std::nullptr_t) const
Definition ne_stl_bind.h:213
static void destroy_fn(Functor *&f)
Definition ne_stl_bind.h:153
_function & operator=(const Functor &f)
Definition ne_stl_bind.h:195
_function(const Functor &f)
Definition ne_stl_bind.h:173
construct_fn_t construct_f
Definition ne_stl_bind.h:235
nstd::shared_ptr< functor_container > data_ptr
Definition ne_stl_bind.h:236
~_ref_flag()
Definition ne_stl_bind.h:245
_ref_flag(const deref_notify_t &_deref_notify)
Definition ne_stl_bind.h:243
deref_notify_t deref_notify
Definition ne_stl_bind.h:249
R operator()(Args... args) const
Definition ne_stl_bind.h:297
function & operator=(std::nullptr_t)
Definition ne_stl_bind.h:278
~function()
Definition ne_stl_bind.h:283
function()
Definition ne_stl_bind.h:254
bool operator!=(const function &other) const
Definition ne_stl_bind.h:287
function(std::nullptr_t)
Definition ne_stl_bind.h:255
bool operator!=(std::nullptr_t) const
Definition ne_stl_bind.h:285
bool operator==(const function &other) const
Definition ne_stl_bind.h:286
function & operator=(const function &rhs)
Definition ne_stl_bind.h:267
R operator()(Args... args)
Definition ne_stl_bind.h:289
bool operator==(std::nullptr_t) const
Definition ne_stl_bind.h:284
function & operator=(const Functor &f)
Definition ne_stl_bind.h:273
function(const Functor &f, const deref_notify_t &deref_notify=nullptr)
Definition ne_stl_bind.h:257
function(const function &rhs)
Definition ne_stl_bind.h:262
Definition ne_stl_bind.h:132
Definition ne_stl_tuple.h:12
Definition ne_stl_bind.h:26
R type
Definition ne_stl_bind.h:27
Definition ne_stl_tuple.h:28
Definition ne_stl_bind.h:45
static void get_i(int32_t &count)
Definition ne_stl_bind.h:53
static int32_t count(const nstd::tuple< TArgs... > &)
Definition ne_stl_bind.h:47
static void get_i(int32_t &count)
Definition ne_stl_bind.h:60
Definition ne_stl_tuple.h:26
Definition ne_stl_bind.h:22
T value
Definition ne_stl_bind.h:23