18 #ifdef AMFUNCTION_DEFAULT_DATA_SIZE 19 static const int _AMFUNCTION_DEFAULT_DATA_SIZE = AMFUNCTION_DEFAULT_DATA_SIZE;
21 static const int _AMFUNCTION_DEFAULT_DATA_SIZE =
sizeof(
void*);
28 template<
typename _Res,
typename ... _ArgTypes>
29 struct _T_AMFN_maybe_unary_or_binary_function {
33 template<
typename _Res,
typename _T1>
34 struct _T_AMFN_maybe_unary_or_binary_function<_Res, _T1>
35 : std::unary_function<_T1, _Res> {
39 template<
typename _Res,
typename _T1,
typename _T2>
40 struct _T_AMFN_maybe_unary_or_binary_function<_Res, _T1, _T2>
41 : std::binary_function<_T1, _T2, _Res> {
45 enum _E_AMFN_manager_operation {
52 struct _T_AMFN_size_base {
53 static unsigned long _M_max;
56 #ifdef COLLECTING_DATA 58 template<
typename _Functor>
59 struct _T_AMFN_size : _T_AMFN_size_base {
61 unsigned long _M_get_size() {
return _M_size;}
63 static int _M_register_size() {
64 if (_M_max <
sizeof(_Functor)) {
65 _M_max =
sizeof(_Functor);
67 return sizeof(_Functor);
69 static unsigned long _M_size;
71 template<
typename _Functor>
72 unsigned long _T_AMFN_size<_Functor>::_M_size = _T_AMFN_size<_Functor>::_M_register_size();
81 template<
typename _Tp>
82 struct _T_AMFN_is_location_invariant : std::is_trivially_copyable<_Tp>::type {
85 template<
typename _From,
typename _To>
86 using _T_AMFN_check_func_return_type = std::__or_<std::is_void<_To>, std::is_same<_From, _To> >;
88 union _T_AMFN_nocopy_types {
90 const void *_M_const_object;
91 char _M_data[_AMFUNCTION_DEFAULT_DATA_SIZE];
94 template<
typename _T,
typename _U> constexpr
size_t _T_AMFN_offset_of(_U _T::*member)
96 return (
char*)&((_T*)nullptr->*member) - (
char*)
nullptr;
99 class _T_AMFN_any_data {
101 _T_AMFN_any_data() {}
103 void *_M_access() {
return &_M_data._M_data[0]; }
105 const void *_M_access()
const {
return &_M_data._M_data[0]; }
107 void *_M_access_ptr() {
return _M_data._M_object; }
109 const void *_M_access_ptr()
const {
return _M_data._M_object; }
111 void _M_set_access_ptr(
void *ptr) { _M_data._M_object = ptr; }
113 template<
typename _Tp>
114 _Tp &_M_get_functor_ptr() {
return *
static_cast<_Tp *
>(_M_data._M_object); }
116 template<
typename _Tp>
117 const _Tp &_M_get_functor_ptr()
const {
return *
static_cast<const _Tp *
>(_M_data._M_object); }
119 template<
typename _Tp>
120 _Tp &_M_get_functor() {
return *
static_cast<_Tp *
>(
static_cast<void *
>(&_M_data._M_data[0])); }
122 template<
typename _Tp>
124 _M_get_functor()
const {
return *
static_cast<const _Tp *
>(
static_cast<const void *
>(&_M_data._M_data[0])); }
126 _T_AMFN_nocopy_types _M_data;
129 template<
typename _Signature>
130 class _T_AMFN_kernel_base;
132 template<
typename _Signature>
133 class _T_AMFN_generic_functor;
135 template<
typename _Res,
typename ... _ArgTypes>
136 class _T_AMFN_generic_functor<_Res(_ArgTypes...)> {
137 _Res operator ()(_ArgTypes ...);
140 template<
typename _Res,
typename ... _ArgTypes>
141 class _T_AMFN_kernel_base<_Res(_ArgTypes...)> {
143 _T_AMFN_any_data _M_functor;
145 typedef _Res (_T_AMFN_generic_functor<_Res(_ArgTypes...)>::*_T_AMFN_invoker_member_type)(_ArgTypes ...)
const;
149 typedef const std::type_info *(*_T_AMFN_kernel_op_ptr)(_T_AMFN_kernel_base *_kernel_ptr,
const _T_AMFN_any_data &_src,
150 _E_AMFN_manager_operation _op);
152 _T_AMFN_kernel_op_ptr _M_kernel_op_ptr;
155 _T_AMFN_kernel_base(_T_AMFN_kernel_op_ptr _kernel_op_ptr) noexcept:
157 _M_invoke_ptr(
nullptr),
158 _M_kernel_op_ptr(_kernel_op_ptr) {};
160 _T_AMFN_kernel_base() noexcept:
162 _M_invoke_ptr(
nullptr),
163 _M_kernel_op_ptr(
nullptr) {};
165 _T_AMFN_kernel_base(
const _T_AMFN_kernel_base &_other) :
167 _M_invoke_ptr(_other._M_invoke_ptr),
168 _M_kernel_op_ptr(_other._M_kernel_op_ptr) {
169 if (_M_kernel_op_ptr) {
170 _M_kernel_op_ptr(
this, _other._M_functor, _clone_functor);
174 _T_AMFN_kernel_base(_T_AMFN_kernel_base &&_other) :
176 _M_invoke_ptr(_other._M_invoke_ptr),
177 _M_kernel_op_ptr(_other._M_kernel_op_ptr) {
178 if (_M_kernel_op_ptr) {
179 _M_kernel_op_ptr(
this, _other._M_functor, _clone_functor_move);
184 ~_T_AMFN_kernel_base() {
185 if (_M_kernel_op_ptr) {
186 _M_kernel_op_ptr(
this, _M_functor, _destroy_functor);
190 _T_AMFN_invoker_member_type _M_get_invoker()
const 193 _T_AMFN_invoker_member_type _M_invoker_member;
194 void* _M_void_ptr_array[2];
196 u._M_void_ptr_array[0] = _M_invoke_ptr;
197 u._M_void_ptr_array[1] =
nullptr;
198 return u._M_invoker_member;
201 _T_AMFN_kernel_base &operator=(
const _T_AMFN_kernel_base &_other) {
202 if (_M_kernel_op_ptr) {
203 _M_kernel_op_ptr(
this, _M_functor, _destroy_functor);
205 _M_invoke_ptr = _other._M_invoke_ptr;
206 _M_kernel_op_ptr = _other._M_kernel_op_ptr;
207 if (_M_kernel_op_ptr) {
208 _M_kernel_op_ptr(
this, _other._M_functor, _clone_functor);
213 const _T_AMFN_any_data &_M_get_functor()
const {
return _M_functor; }
217 if (_M_kernel_op_ptr) {
218 _M_kernel_op_ptr(
this, _M_functor, _destroy_functor);
220 _M_invoke_ptr =
nullptr;
221 _M_kernel_op_ptr =
nullptr;
224 bool _M_empty() const noexcept {
225 return _M_invoke_ptr ==
nullptr;
230 const std::type_info &_M_get_type_info() const noexcept {
234 _T_AMFN_kernel_base *nonconstthis =
const_cast<_T_AMFN_kernel_base *
>(
this);
235 return *_M_kernel_op_ptr(nonconstthis, _M_functor, _get_type_info);
241 template<
typename _Signature,
typename _Functor>
242 class _T_AMFN_kernel;
244 template<
typename _Signature,
typename _Functor>
245 class _AMFunction_handler;
247 template<
typename _Res,
typename _Functor,
typename ... _ArgTypes>
248 class _T_AMFN_kernel<_Res(_ArgTypes ...), _Functor>
249 :
public _T_AMFN_kernel_base<_Res(_ArgTypes...)> {
251 static const std::size_t _M_max_size =
sizeof(_T_AMFN_nocopy_types);
252 static const std::size_t _M_max_align = __alignof__(_T_AMFN_nocopy_types);
254 static const bool _C_stored_locally =
255 (_T_AMFN_is_location_invariant<_Functor>::value
256 && (
sizeof(_Functor) <= _M_max_size)
257 && (__alignof__(_Functor) <= _M_max_align)
258 && (_M_max_align % __alignof__(_Functor) == 0))
259 && (_AMFUNCTION_DEFAULT_DATA_SIZE > 0);
260 typedef std::integral_constant<bool, _C_stored_locally> _Local_storage;
261 typedef _T_AMFN_kernel_base<_Res(_ArgTypes...)> _T_Base;
263 void _M_clone(
const _T_AMFN_any_data &_functor, std::true_type) {
264 _Functor *vp = &_T_Base::_M_functor.template _M_get_functor<_Functor>();
265 ::new(vp) _Functor(_functor.template _M_get_functor<_Functor>());
268 void _M_clone(
const _T_AMFN_any_data &_functor, std::false_type) {
270 rv =
static_cast<void *
>(
new _Functor(_functor.template _M_get_functor_ptr<_Functor>()));
271 _T_Base::_M_functor._M_set_access_ptr(rv);
274 void _M_move(
const _T_AMFN_any_data &_functor, std::true_type) {
275 _Functor *vp = &_T_Base::_M_functor.template _M_get_functor<_Functor>();
276 ::new(vp) _Functor(std::move(_functor.template _M_get_functor<_Functor>()));
279 void _M_move(
const _T_AMFN_any_data &_functor, std::false_type) {
281 rv =
static_cast<void *
>(
new _Functor(std::move(_functor.template _M_get_functor_ptr<_Functor>())));
282 _T_Base::_M_functor._M_set_access_ptr(rv);
285 void _M_init(
const _Functor &_source, std::true_type) {
286 _Functor *vp = &_T_Base::_M_functor.template _M_get_functor<_Functor>();
287 ::new(vp) _Functor(_source);
290 void _M_init(
const _Functor &_source, std::false_type) {
292 rv =
static_cast<void *
>(
new _Functor(_source));
293 _T_Base::_M_functor._M_set_access_ptr(rv);
296 void _M_destroy(std::true_type) {
297 _T_Base::_M_functor.template _M_get_functor<_Functor>().~_Functor();
300 void _M_destroy(std::false_type) {
301 delete &_T_Base::_M_functor.template _M_get_functor_ptr<_Functor>();
304 static const std::type_info *
305 _M_manage_op(_T_AMFN_kernel_base<_Res(_ArgTypes ...)> *_me,
const _T_AMFN_any_data &_functor,
306 _E_AMFN_manager_operation _op) {
308 case _destroy_functor:
309 static_cast<_T_AMFN_kernel *
>(_me)->_M_destroy(_Local_storage());
312 static_cast<_T_AMFN_kernel *
>(_me)->_M_clone(_functor, _Local_storage());
314 case _clone_functor_move:
315 static_cast<_T_AMFN_kernel *
>(_me)->_M_move(_functor, _Local_storage());
319 return &
typeid(_Functor);
327 typedef _Res (_AMFunction_handler<_Res(_ArgTypes...), _Functor>::*_T_AMFN_invoker_member_type)(_ArgTypes ...);
328 typedef _Res (_Functor::*_Invoker_functor_type)(_ArgTypes...)
const;
330 void _M_set_invoker(_Invoker_functor_type _invoker)
333 _Invoker_functor_type _M_invoker_member;
334 void* _M_void_ptr_array[2];
336 u._M_invoker_member = _invoker;
337 if (u._M_void_ptr_array[1] !=
nullptr) {
338 throw std::bad_function_call();
340 _T_Base::_M_invoke_ptr = u._M_void_ptr_array[0];
343 void _M_set_invoker_member(_T_AMFN_invoker_member_type _invoker)
346 _T_AMFN_invoker_member_type _M_invoker_member;
347 void* _M_void_ptr_array[2];
349 u._M_invoker_member = _invoker;
350 if (u._M_void_ptr_array[1] !=
nullptr) {
351 throw std::bad_function_call();
353 _T_Base::_M_invoke_ptr = u._M_void_ptr_array[0];
358 _T_AMFN_kernel(
const _Functor &_functor, _T_AMFN_invoker_member_type invoke_ptr) :
359 _T_AMFN_kernel_base<_Res(_ArgTypes...)>(
362 if (_C_stored_locally) {
363 _M_set_invoker(&_Functor::operator ());
366 _M_set_invoker_member(invoke_ptr);
368 _M_init(_functor, _Local_storage());
373 template<
typename _Res,
typename _Functor,
typename... _ArgTypes>
374 class _AMFunction_handler<_Res(_ArgTypes...), _Functor>
375 :
public _T_AMFN_kernel<_Res(_ArgTypes...), _Functor> {
376 typedef _T_AMFN_kernel<_Res(_ArgTypes...), _Functor> _T_Base;
379 _AMFunction_handler(_Functor _functor) : _T_Base(_functor, &_AMFunction_handler<_Res(_ArgTypes...), _Functor>::_M_invoke) {}
381 _Res _M_invoke(_ArgTypes ... __args) {
382 const void* newvfunctor = _T_Base::_M_get_functor()._M_access_ptr();
383 const _Functor& newfunctor = *
static_cast<const _Functor*
>(newvfunctor);
384 return newfunctor(std::forward<_ArgTypes>(__args)...);
389 template<
typename _Functor,
typename... _ArgTypes>
390 class _AMFunction_handler<void(_ArgTypes...), _Functor>
391 :
public _T_AMFN_kernel<void(_ArgTypes...), _Functor> {
392 typedef _T_AMFN_kernel<void(_ArgTypes...), _Functor> _T_Base;
395 _AMFunction_handler(_Functor _functor) : _T_Base(_functor, &_AMFunction_handler<void(_ArgTypes...), _Functor>::_M_invoke) {}
397 void _M_invoke(_ArgTypes ... __args) {
398 const void* newvfunctor = _T_Base::_M_get_functor()._M_access_ptr();
399 const _Functor& newfunctor = *
static_cast<const _Functor*
>(newvfunctor);
400 newfunctor(std::forward<_ArgTypes>(__args)...);
404 template<
typename _Signature>
436 template<
typename _Res,
typename ... _ArgTypes>
437 class AMFunction<_Res(_ArgTypes ...)>
438 :
public _T_AMFN_maybe_unary_or_binary_function<_Res, _ArgTypes ...> {
440 _T_AMFN_kernel_base<_Res(_ArgTypes...)> _M_kernel;
442 template<
typename _Func,
443 typename _Res2 =
typename std::result_of<_Func &(_ArgTypes ...)>::type>
444 struct _Callable : _T_AMFN_check_func_return_type<_Res2, _Res> {
447 template<
typename _Tp>
448 struct _Callable<AMFunction, _Tp> : std::false_type {
451 template<
typename _Cond,
typename _Tp>
452 using _Requires =
typename std::enable_if<_Cond::value, _Tp>::type;
478 AMFunction(
const AMFunction<_Res(_ArgTypes...)> &_other) : _M_kernel(_other._M_kernel) {}
490 AMFunction(AMFunction<_Res(_ArgTypes...)> &&_other) : _M_kernel(
std::move(_other._M_kernel)) {}
500 template<
typename _Functor,
501 typename = _Requires<std::__not_<std::is_same<_Functor, AMFunction> >,
void>,
502 typename = _Requires<_Callable<_Functor>,
void> >
503 AMFunction(_Functor _f);
517 if (!_M_kernel._M_empty()) {
518 _M_kernel._M_destroy();
520 _M_kernel = _other._M_kernel;
535 if (!_M_kernel._M_empty()) {
536 _M_kernel._M_destroy();
538 _M_kernel = std::move(_other._M_kernel);
551 if (!_M_kernel._M_empty()) {
552 _M_kernel._M_destroy();
567 template<
typename _Functor>
568 _Requires<_Callable<typename std::decay<_Functor>::type>, AMFunction &>
570 #ifdef COLLECTING_DATA 571 static _T_AMFN_size<_Functor> _functor_size;
572 _functor_size._M_get_size();
574 if (!_M_kernel._M_empty()) {
575 _M_kernel._M_destroy();
577 typedef _AMFunction_handler<_Res(_ArgTypes...), _Functor> _My_handler;
578 ::new(&_M_kernel) _My_handler(_f);
590 explicit operator bool() const noexcept {
591 return !_M_kernel._M_empty();
603 if (_M_kernel._M_empty()) {
604 throw std::bad_function_call();
606 const _T_AMFN_generic_functor<_Res(_ArgTypes...)>& obj = _M_kernel._M_get_functor().template _M_get_functor<_T_AMFN_generic_functor<_Res(_ArgTypes...)> >();
607 typedef _Res (_T_AMFN_generic_functor<_Res(_ArgTypes...)>::*_T_AMFN_invoker_member_type)(_ArgTypes ...)
const;
608 _T_AMFN_invoker_member_type memberfn = _M_kernel._M_get_invoker();
609 _Res rv = ((obj).*(memberfn))(std::forward<_ArgTypes>(__args)...);
622 const std::type_info &target_type()
const noexcept {
623 const std::type_info &_typeinfo_result = _M_kernel._M_get_type_info();
624 return _typeinfo_result;
645 unsigned long _return_value = -1;
646 #ifdef COLLECTING_DATA 647 _return_value = _T_AMFN_size_base::_M_max;
649 return _return_value;
653 template<
typename _Res,
typename ... _ArgTypes>
654 template<
typename _Functor,
typename,
typename>
655 AMFunction<_Res(_ArgTypes...)>::AMFunction(_Functor __f) {
656 #ifdef COLLECTING_DATA 657 static _T_AMFN_size<_Functor> _functor_size;
658 _functor_size._M_get_size();
660 typedef _AMFunction_handler<_Res(_ArgTypes...), _Functor> _My_handler;
661 ::new(&_M_kernel) _My_handler(__f);
672 template<
typename _Res,
typename ... _Args>
674 operator==(
const AMFunction<_Res(_Args ...)> &__f, std::nullptr_t) noexcept {
675 return !
static_cast<bool>(__f);
686 template<
typename _Res,
typename ... _Args>
688 operator==(std::nullptr_t,
const AMFunction<_Res(_Args ...)> &__f) noexcept {
689 return !
static_cast<bool>(__f);
699 template<
typename _Res,
typename ... _Args>
701 operator!=(
const AMFunction<_Res(_Args ...)> &__f, std::nullptr_t) noexcept {
702 return static_cast<bool>(__f);
712 template<
typename _Res,
typename ... _Args>
714 operator!=(std::nullptr_t,
const AMFunction<_Res(_Args ...)> &__f) noexcept {
715 return static_cast<bool>(__f);
720 #endif //AMFUNCTION_H AMFunction & operator=(const AMFunction &_other)
AMFunction assignment operator.
Definition: AMFunction.h:516
AMFunction & operator=(std::nullptr_t)
AMFunction assignment to zero.
Definition: AMFunction.h:550
Definition: AMProperty.h:32
AMFunction & operator=(AMFunction &&_other)
AMFunction move-assignment operator.
Definition: AMFunction.h:534
_Requires< _Callable< typename std::decay< _Functor >::type >, AMFunction & > operator=(_Functor &_f)
AMFunction assignment to a new target.
Definition: AMFunction.h:569
bool operator!=(std::nullptr_t, const AMFunction< _Res(_Args ...)> &__f) noexcept
Compares an AMFunction target with nullptr.
Definition: AMFunction.h:714
_Res operator()(_ArgTypes ... __args) const
Invokes the AMFunction targeted by *this.
Definition: AMFunction.h:602
static unsigned long getMaximumFunctorSize() noexcept
Determines maximum functor size used in program.
Definition: AMFunction.h:643
AMFunction() noexcept
Default construct creates an empty AMFunction.
Definition: AMFunction.h:461
Definition: AMFunction.h:16
bool operator==(std::nullptr_t, const AMFunction< _Res(_Args ...)> &__f) noexcept
Compares an AMFunction target with nullptr.
Definition: AMFunction.h:688
AMFunction(std::nullptr_t) noexcept
Creates an empty AMFunction.
Definition: AMFunction.h:467
AMFunction(AMFunction< _Res(_ArgTypes...)> &&_other)
AMFunction move constructor.
Definition: AMFunction.h:490
AMFunction(const AMFunction< _Res(_ArgTypes...)> &_other)
AMFunction copy constructor.
Definition: AMFunction.h:478