1 // TR1 functional -*- C++ -*-
3 // Copyright (C) 2005 Free Software Foundation, Inc.
4 // Written by Douglas Gregor <doug.gregor -at- gmail.com>
6 // This file is part of the GNU ISO C++ Library. This library is free
7 // software; you can redistribute it and/or modify it under the
8 // terms of the GNU General Public License as published by the
9 // Free Software Foundation; either version 2, or (at your option)
12 // This library is distributed in the hope that it will be useful,
13 // but WITHOUT ANY WARRANTY; without even the implied warranty of
14 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 // GNU General Public License for more details.
17 // You should have received a copy of the GNU General Public License along
18 // with this library; see the file COPYING. If not, write to the Free
19 // Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
22 // As a special exception, you may use this file as part of a free software
23 // library without restriction. Specifically, if other files instantiate
24 // templates or use macros or inline functions from this file, or you compile
25 // this file and link it with other files to produce an executable, this
26 // file does not by itself cause the resulting executable to be covered by
27 // the GNU General Public License. This exception does not however
28 // invalidate any other reasons why the executable file might be covered by
29 // the GNU General Public License.
31 /** @file functional_iterate.h
32 * This is an internal header file, included by other library headers.
33 * You should not attempt to use it directly.
36 template<typename _Res _GLIBCXX_COMMA _GLIBCXX_TEMPLATE_PARAMS
>
37 struct _Weak_result_type_impl
<_Res(_GLIBCXX_TEMPLATE_ARGS
)>
39 typedef _Res result_type
;
42 template<typename _Res _GLIBCXX_COMMA _GLIBCXX_TEMPLATE_PARAMS
>
43 struct _Weak_result_type_impl
<_Res (&)(_GLIBCXX_TEMPLATE_ARGS
)>
45 typedef _Res result_type
;
48 template<typename _Res _GLIBCXX_COMMA _GLIBCXX_TEMPLATE_PARAMS
>
49 struct _Weak_result_type_impl
<_Res (*)(_GLIBCXX_TEMPLATE_ARGS
)>
51 typedef _Res result_type
;
54 #if _GLIBCXX_NUM_ARGS > 0
55 template<typename _Res
, typename _Class _GLIBCXX_COMMA_SHIFTED
56 _GLIBCXX_TEMPLATE_PARAMS_SHIFTED
>
57 struct _Weak_result_type_impl
<
58 _Res (_Class::*)(_GLIBCXX_TEMPLATE_ARGS_SHIFTED
)>
60 typedef _Res result_type
;
63 template<typename _Res
, typename _Class _GLIBCXX_COMMA_SHIFTED
64 _GLIBCXX_TEMPLATE_PARAMS_SHIFTED
>
65 struct _Weak_result_type_impl
<
66 _Res (_Class::*)(_GLIBCXX_TEMPLATE_ARGS_SHIFTED
) const>
68 typedef _Res result_type
;
71 template<typename _Res
, typename _Class _GLIBCXX_COMMA_SHIFTED
72 _GLIBCXX_TEMPLATE_PARAMS_SHIFTED
>
73 struct _Weak_result_type_impl
<
74 _Res (_Class::*)(_GLIBCXX_TEMPLATE_ARGS_SHIFTED
) volatile>
76 typedef _Res result_type
;
79 template<typename _Res
, typename _Class _GLIBCXX_COMMA_SHIFTED
80 _GLIBCXX_TEMPLATE_PARAMS_SHIFTED
>
81 struct _Weak_result_type_impl
<
82 _Res (_Class::*)(_GLIBCXX_TEMPLATE_ARGS_SHIFTED
) const volatile>
84 typedef _Res result_type
;
88 template<typename _Functor _GLIBCXX_COMMA _GLIBCXX_TEMPLATE_PARAMS
>
89 class result_of
<_Functor(_GLIBCXX_TEMPLATE_ARGS
)>
90 : public _Result_of_impl
<
91 _Has_result_type
<_Weak_result_type
<_Functor
> >::value
,
92 _Functor(_GLIBCXX_TEMPLATE_ARGS
)>
95 template<typename _Functor _GLIBCXX_COMMA _GLIBCXX_TEMPLATE_PARAMS
>
96 struct _Result_of_impl
<true, _Functor(_GLIBCXX_TEMPLATE_ARGS
)>
98 typedef typename _Weak_result_type
<_Functor
>::result_type type
;
101 template<typename _Functor _GLIBCXX_COMMA _GLIBCXX_TEMPLATE_PARAMS
>
102 struct _Result_of_impl
<false, _Functor(_GLIBCXX_TEMPLATE_ARGS
)>
104 #if _GLIBCXX_NUM_ARGS > 0
105 typedef typename _Functor
106 ::template result
<_Functor(_GLIBCXX_TEMPLATE_ARGS
)>::type type
;
114 * Invoke a function object, which may be either a member pointer or a
115 * function object. The first parameter will tell which.
118 template<typename _Functor _GLIBCXX_COMMA _GLIBCXX_TEMPLATE_PARAMS
>
120 typename __enable_if
<
121 typename result_of
<_Functor(_GLIBCXX_TEMPLATE_ARGS
)>::type
,
122 (!is_member_pointer
<_Functor
>::value
123 && !is_function
<_Functor
>::value
124 && !is_function
<typename remove_pointer
<_Functor
>::type
>::value
)
126 __invoke(_Functor
& __f _GLIBCXX_COMMA _GLIBCXX_REF_PARAMS
)
128 return __f(_GLIBCXX_ARGS
);
131 #if _GLIBCXX_NUM_ARGS > 0
132 template<typename _Functor _GLIBCXX_COMMA _GLIBCXX_TEMPLATE_PARAMS
>
134 typename __enable_if
<
135 typename result_of
<_Functor(_GLIBCXX_TEMPLATE_ARGS
)>::type
,
136 (is_member_pointer
<_Functor
>::value
137 && !is_function
<_Functor
>::value
138 && !is_function
<typename remove_pointer
<_Functor
>::type
>::value
)
140 __invoke(_Functor
& __f _GLIBCXX_COMMA _GLIBCXX_REF_PARAMS
)
142 return mem_fn(__f
)(_GLIBCXX_ARGS
);
146 // To pick up function references (that will become function pointers)
147 template<typename _Functor _GLIBCXX_COMMA _GLIBCXX_TEMPLATE_PARAMS
>
149 typename __enable_if
<
150 typename result_of
<_Functor(_GLIBCXX_TEMPLATE_ARGS
)>::type
,
151 (is_pointer
<_Functor
>::value
152 && is_function
<typename remove_pointer
<_Functor
>::type
>::value
)
154 __invoke(_Functor __f _GLIBCXX_COMMA _GLIBCXX_REF_PARAMS
)
156 return __f(_GLIBCXX_ARGS
);
161 * Implementation of reference_wrapper::operator()
164 #if _GLIBCXX_NUM_ARGS > 0
165 template<typename _Tp
>
166 template<_GLIBCXX_TEMPLATE_PARAMS
>
168 typename reference_wrapper
<_Tp
>::_M_func_type(_GLIBCXX_TEMPLATE_ARGS
)>::type
169 reference_wrapper
<_Tp
>::operator()(_GLIBCXX_REF_PARAMS
) const
171 return __invoke(get(), _GLIBCXX_ARGS
);
175 #if _GLIBCXX_NUM_ARGS > 0
176 template<typename _Res
, typename _Class _GLIBCXX_COMMA_SHIFTED
177 _GLIBCXX_TEMPLATE_PARAMS_SHIFTED
>
178 class _Mem_fn
<_Res (_Class::*)(_GLIBCXX_TEMPLATE_ARGS_SHIFTED
)>
179 #if _GLIBCXX_NUM_ARGS == 1
180 : public unary_function
<_Class
*, _Res
>
181 #elif _GLIBCXX_NUM_ARGS == 2
182 : public binary_function
<_Class
*, _T1
, _Res
>
185 typedef _Res (_Class::*_Functor
)(_GLIBCXX_TEMPLATE_ARGS_SHIFTED
);
187 template<typename _Tp
>
189 _M_call(_Tp
& __object
, const volatile _Class
* _GLIBCXX_COMMA_SHIFTED
190 _GLIBCXX_PARAMS_SHIFTED
) const
191 { return (__object
.*__pmf
)(_GLIBCXX_ARGS_SHIFTED
); }
193 template<typename _Tp
>
195 _M_call(_Tp
& __ptr
, const volatile void * _GLIBCXX_COMMA_SHIFTED
196 _GLIBCXX_PARAMS_SHIFTED
) const
197 { return ((*__ptr
).*__pmf
)(_GLIBCXX_ARGS_SHIFTED
); }
200 typedef _Res result_type
;
202 explicit _Mem_fn(_Functor __pmf
) : __pmf(__pmf
) { }
206 operator()(_Class
& __object _GLIBCXX_COMMA_SHIFTED
207 _GLIBCXX_PARAMS_SHIFTED
) const
208 { return (__object
.*__pmf
)(_GLIBCXX_ARGS_SHIFTED
); }
212 operator()(_Class
* __object _GLIBCXX_COMMA_SHIFTED
213 _GLIBCXX_PARAMS_SHIFTED
) const
214 { return (__object
->*__pmf
)(_GLIBCXX_ARGS_SHIFTED
); }
216 // Handle smart pointers, references and pointers to derived
217 template<typename _Tp
>
219 operator()(_Tp
& __object _GLIBCXX_COMMA_SHIFTED
220 _GLIBCXX_PARAMS_SHIFTED
) const
222 return _M_call(__object
, &__object _GLIBCXX_COMMA_SHIFTED
223 _GLIBCXX_ARGS_SHIFTED
);
230 template<typename _Res
, typename _Class _GLIBCXX_COMMA_SHIFTED
231 _GLIBCXX_TEMPLATE_PARAMS_SHIFTED
>
232 class _Mem_fn
<_Res (_Class::*)(_GLIBCXX_TEMPLATE_ARGS_SHIFTED
) const>
233 #if _GLIBCXX_NUM_ARGS == 1
234 : public unary_function
<const _Class
*, _Res
>
235 #elif _GLIBCXX_NUM_ARGS == 2
236 : public binary_function
<const _Class
*, _T1
, _Res
>
239 typedef _Res (_Class::*_Functor
)(_GLIBCXX_TEMPLATE_ARGS_SHIFTED
) const;
241 template<typename _Tp
>
243 _M_call(_Tp
& __object
, const volatile _Class
* _GLIBCXX_COMMA_SHIFTED
244 _GLIBCXX_PARAMS_SHIFTED
) const
245 { return (__object
.*__pmf
)(_GLIBCXX_ARGS_SHIFTED
); }
247 template<typename _Tp
>
249 _M_call(_Tp
& __ptr
, const volatile void * _GLIBCXX_COMMA_SHIFTED
250 _GLIBCXX_PARAMS_SHIFTED
) const
251 { return ((*__ptr
).*__pmf
)(_GLIBCXX_ARGS_SHIFTED
); }
254 typedef _Res result_type
;
256 explicit _Mem_fn(_Functor __pmf
) : __pmf(__pmf
) { }
260 operator()(const _Class
& __object _GLIBCXX_COMMA_SHIFTED
261 _GLIBCXX_PARAMS_SHIFTED
) const
262 { return (__object
.*__pmf
)(_GLIBCXX_ARGS_SHIFTED
); }
266 operator()(const _Class
* __object _GLIBCXX_COMMA_SHIFTED
267 _GLIBCXX_PARAMS_SHIFTED
) const
268 { return (__object
->*__pmf
)(_GLIBCXX_ARGS_SHIFTED
); }
270 // Handle smart pointers, references and pointers to derived
271 template<typename _Tp
>
273 operator()(_Tp
& __object _GLIBCXX_COMMA_SHIFTED
274 _GLIBCXX_PARAMS_SHIFTED
) const
276 return _M_call(__object
, &__object _GLIBCXX_COMMA_SHIFTED
277 _GLIBCXX_ARGS_SHIFTED
);
284 template<typename _Res
, typename _Class _GLIBCXX_COMMA_SHIFTED
285 _GLIBCXX_TEMPLATE_PARAMS_SHIFTED
>
286 class _Mem_fn
<_Res (_Class::*)(_GLIBCXX_TEMPLATE_ARGS_SHIFTED
) volatile>
287 #if _GLIBCXX_NUM_ARGS == 1
288 : public unary_function
<volatile _Class
*, _Res
>
289 #elif _GLIBCXX_NUM_ARGS == 2
290 : public binary_function
<volatile _Class
*, _T1
, _Res
>
293 typedef _Res (_Class::*_Functor
)(_GLIBCXX_TEMPLATE_ARGS_SHIFTED
) volatile;
295 template<typename _Tp
>
297 _M_call(_Tp
& __object
, const volatile _Class
* _GLIBCXX_COMMA_SHIFTED
298 _GLIBCXX_PARAMS_SHIFTED
) const
299 { return (__object
.*__pmf
)(_GLIBCXX_ARGS_SHIFTED
); }
301 template<typename _Tp
>
303 _M_call(_Tp
& __ptr
, const volatile void * _GLIBCXX_COMMA_SHIFTED
304 _GLIBCXX_PARAMS_SHIFTED
) const
305 { return ((*__ptr
).*__pmf
)(_GLIBCXX_ARGS_SHIFTED
); }
308 typedef _Res result_type
;
310 explicit _Mem_fn(_Functor __pmf
) : __pmf(__pmf
) { }
314 operator()(volatile _Class
& __object _GLIBCXX_COMMA_SHIFTED
315 _GLIBCXX_PARAMS_SHIFTED
) const
316 { return (__object
.*__pmf
)(_GLIBCXX_ARGS_SHIFTED
); }
320 operator()(volatile _Class
* __object _GLIBCXX_COMMA_SHIFTED
321 _GLIBCXX_PARAMS_SHIFTED
) const
322 { return (__object
->*__pmf
)(_GLIBCXX_ARGS_SHIFTED
); }
324 // Handle smart pointers, references and pointers to derived
325 template<typename _Tp
>
327 operator()(_Tp
& __object _GLIBCXX_COMMA_SHIFTED
328 _GLIBCXX_PARAMS_SHIFTED
) const
330 return _M_call(__object
, &__object _GLIBCXX_COMMA_SHIFTED
331 _GLIBCXX_ARGS_SHIFTED
);
337 template<typename _Res
, typename _Class _GLIBCXX_COMMA_SHIFTED
338 _GLIBCXX_TEMPLATE_PARAMS_SHIFTED
>
339 class _Mem_fn
<_Res(_Class::*)(_GLIBCXX_TEMPLATE_ARGS_SHIFTED
) const volatile>
340 #if _GLIBCXX_NUM_ARGS == 1
341 : public unary_function
<const volatile _Class
*, _Res
>
342 #elif _GLIBCXX_NUM_ARGS == 2
343 : public binary_function
<const volatile _Class
*, _T1
, _Res
>
346 typedef _Res (_Class::*_Functor
)(_GLIBCXX_TEMPLATE_ARGS_SHIFTED
)
349 template<typename _Tp
>
351 _M_call(_Tp
& __object
, const volatile _Class
* _GLIBCXX_COMMA_SHIFTED
352 _GLIBCXX_PARAMS_SHIFTED
) const
353 { return (__object
.*__pmf
)(_GLIBCXX_ARGS_SHIFTED
); }
355 template<typename _Tp
>
357 _M_call(_Tp
& __ptr
, const volatile void * _GLIBCXX_COMMA_SHIFTED
358 _GLIBCXX_PARAMS_SHIFTED
) const
359 { return ((*__ptr
).*__pmf
)(_GLIBCXX_ARGS_SHIFTED
); }
362 typedef _Res result_type
;
364 explicit _Mem_fn(_Functor __pmf
) : __pmf(__pmf
) { }
368 operator()(const volatile _Class
& __object _GLIBCXX_COMMA_SHIFTED
369 _GLIBCXX_PARAMS_SHIFTED
) const
370 { return (__object
.*__pmf
)(_GLIBCXX_ARGS_SHIFTED
); }
374 operator()(const volatile _Class
* __object _GLIBCXX_COMMA_SHIFTED
375 _GLIBCXX_PARAMS_SHIFTED
) const
376 { return (__object
->*__pmf
)(_GLIBCXX_ARGS_SHIFTED
); }
378 // Handle smart pointers, references and pointers to derived
379 template<typename _Tp
>
381 operator()(_Tp
& __object _GLIBCXX_COMMA_SHIFTED
382 _GLIBCXX_PARAMS_SHIFTED
) const
384 return _M_call(__object
, &__object _GLIBCXX_COMMA_SHIFTED
385 _GLIBCXX_ARGS_SHIFTED
);
393 #if _GLIBCXX_NUM_ARGS > 0
394 namespace placeholders
398 _Placeholder
<_GLIBCXX_NUM_ARGS
> _GLIBCXX_JOIN(_
,_GLIBCXX_NUM_ARGS
);
403 template<typename _Functor _GLIBCXX_COMMA _GLIBCXX_TEMPLATE_PARAMS
>
404 class _Bind
<_Functor(_GLIBCXX_TEMPLATE_ARGS
)>
405 : public _Weak_result_type
<_Functor
>
407 typedef _Bind __self_type
;
410 _GLIBCXX_BIND_MEMBERS
413 #if _GLIBCXX_NUM_ARGS == 0
416 _Bind(_Functor __f _GLIBCXX_COMMA _GLIBCXX_PARAMS
)
417 : _M_f(__f
) _GLIBCXX_COMMA _GLIBCXX_BIND_MEMBERS_INIT
{ }
419 #define _GLIBCXX_BIND_REPEAT_HEADER <tr1/bind_iterate.h>
420 #include <tr1/bind_repeat.h>
421 #undef _GLIBCXX_BIND_REPEAT_HEADER
424 template<typename _Result
, typename _Functor
425 _GLIBCXX_COMMA _GLIBCXX_TEMPLATE_PARAMS
>
426 class _Bind_result
<_Result
, _Functor(_GLIBCXX_TEMPLATE_ARGS
)>
429 _GLIBCXX_BIND_MEMBERS
432 typedef _Result result_type
;
434 #if _GLIBCXX_NUM_ARGS == 0
437 _Bind_result(_Functor __f _GLIBCXX_COMMA _GLIBCXX_PARAMS
)
438 : _M_f(__f
) _GLIBCXX_COMMA _GLIBCXX_BIND_MEMBERS_INIT
{ }
440 #define _GLIBCXX_BIND_REPEAT_HEADER <tr1/bind_iterate.h>
441 #define _GLIBCXX_BIND_HAS_RESULT_TYPE
442 #include <tr1/bind_repeat.h>
443 #undef _GLIBCXX_BIND_HAS_RESULT_TYPE
444 #undef _GLIBCXX_BIND_REPEAT_HEADER
447 // Handle arbitrary function objects
448 template<typename _Functor _GLIBCXX_COMMA _GLIBCXX_TEMPLATE_PARAMS
>
450 _Bind
<typename _Maybe_wrap_member_pointer
<_Functor
>::type
451 (_GLIBCXX_TEMPLATE_ARGS
)>
452 bind(_Functor __f _GLIBCXX_COMMA _GLIBCXX_PARAMS
)
454 typedef _Maybe_wrap_member_pointer
<_Functor
> __maybe_type
;
455 typedef typename
__maybe_type::type __functor_type
;
456 typedef _Bind
<__functor_type(_GLIBCXX_TEMPLATE_ARGS
)> __result_type
;
457 return __result_type(__maybe_type::__do_wrap(__f
)
458 _GLIBCXX_COMMA _GLIBCXX_ARGS
);
461 template<typename _Result
, typename _Functor
462 _GLIBCXX_COMMA _GLIBCXX_TEMPLATE_PARAMS
>
464 _Bind_result
<_Result
,
465 typename _Maybe_wrap_member_pointer
<_Functor
>::type
466 (_GLIBCXX_TEMPLATE_ARGS
)>
467 bind(_Functor __f _GLIBCXX_COMMA _GLIBCXX_PARAMS
)
469 typedef _Maybe_wrap_member_pointer
<_Functor
> __maybe_type
;
470 typedef typename
__maybe_type::type __functor_type
;
471 typedef _Bind_result
<_Result
, __functor_type(_GLIBCXX_TEMPLATE_ARGS
)>
473 return __result_type(__maybe_type::__do_wrap(__f
)
474 _GLIBCXX_COMMA _GLIBCXX_ARGS
);
477 template<typename _Res
, typename _Functor _GLIBCXX_COMMA
478 _GLIBCXX_TEMPLATE_PARAMS
>
479 class _Function_handler
<_Res(_GLIBCXX_TEMPLATE_ARGS
), _Functor
>
480 : public _Function_base::_Base_manager
<_Functor
>
482 typedef _Function_base::_Base_manager
<_Functor
> _Base
;
486 _M_invoke(const _Any_data
& __functor _GLIBCXX_COMMA _GLIBCXX_PARAMS
)
488 return (*_Base::_M_get_pointer(__functor
))(_GLIBCXX_ARGS
);
492 template<typename _Functor _GLIBCXX_COMMA _GLIBCXX_TEMPLATE_PARAMS
>
493 class _Function_handler
<void(_GLIBCXX_TEMPLATE_ARGS
), _Functor
>
494 : public _Function_base::_Base_manager
<_Functor
>
496 typedef _Function_base::_Base_manager
<_Functor
> _Base
;
500 _M_invoke(const _Any_data
& __functor _GLIBCXX_COMMA _GLIBCXX_PARAMS
)
502 (*_Base::_M_get_pointer(__functor
))(_GLIBCXX_ARGS
);
506 template<typename _Res
, typename _Functor _GLIBCXX_COMMA
507 _GLIBCXX_TEMPLATE_PARAMS
>
508 class _Function_handler
<_Res(_GLIBCXX_TEMPLATE_ARGS
),
509 reference_wrapper
<_Functor
> >
510 : public _Function_base::_Ref_manager
<_Functor
>
512 typedef _Function_base::_Ref_manager
<_Functor
> _Base
;
516 _M_invoke(const _Any_data
& __functor _GLIBCXX_COMMA _GLIBCXX_PARAMS
)
518 return __callable_functor(**_Base::_M_get_pointer(__functor
))
523 template<typename _Functor _GLIBCXX_COMMA _GLIBCXX_TEMPLATE_PARAMS
>
524 class _Function_handler
<void(_GLIBCXX_TEMPLATE_ARGS
),
525 reference_wrapper
<_Functor
> >
526 : public _Function_base::_Ref_manager
<_Functor
>
528 typedef _Function_base::_Ref_manager
<_Functor
> _Base
;
532 _M_invoke(const _Any_data
& __functor _GLIBCXX_COMMA _GLIBCXX_PARAMS
)
534 __callable_functor(**_Base::_M_get_pointer(__functor
))(_GLIBCXX_ARGS
);
538 template<typename _Class
, typename _Member
, typename _Res
539 _GLIBCXX_COMMA _GLIBCXX_TEMPLATE_PARAMS
>
540 class _Function_handler
<_Res(_GLIBCXX_TEMPLATE_ARGS
), _Member
_Class::*>
541 : public _Function_handler
<void(_GLIBCXX_TEMPLATE_ARGS
), _Member
_Class::*>
543 typedef _Function_handler
<void(_GLIBCXX_TEMPLATE_ARGS
), _Member
_Class::*>
548 _M_invoke(const _Any_data
& __functor _GLIBCXX_COMMA _GLIBCXX_PARAMS
)
550 return std::tr1::mem_fn(_Base::_M_get_pointer(__functor
)->__value
)
555 template<typename _Class
, typename _Member
556 _GLIBCXX_COMMA _GLIBCXX_TEMPLATE_PARAMS
>
557 class _Function_handler
<void(_GLIBCXX_TEMPLATE_ARGS
), _Member
_Class::*>
558 : public _Function_base::_Base_manager
<
559 _Simple_type_wrapper
< _Member
_Class::* > >
561 typedef _Member
_Class::* _Functor
;
562 typedef _Simple_type_wrapper
< _Functor
> _Wrapper
;
563 typedef _Function_base::_Base_manager
<_Wrapper
> _Base
;
567 _M_manager(_Any_data
& __dest
, const _Any_data
& __source
,
568 _Manager_operation __op
)
571 case __get_type_info
:
572 __dest
._M_access
<const type_info
*>() = &typeid(_Functor
);
575 case __get_functor_ptr
:
576 __dest
._M_access
<_Functor
*>() =
577 &_Base::_M_get_pointer(__source
)->__value
;
581 _Base::_M_manager(__dest
, __source
, __op
);
587 _M_invoke(const _Any_data
& __functor _GLIBCXX_COMMA _GLIBCXX_PARAMS
)
589 std::tr1::mem_fn(_Base::_M_get_pointer(__functor
)->__value
)
594 template<typename _Res _GLIBCXX_COMMA _GLIBCXX_TEMPLATE_PARAMS
>
595 class function
<_Res(_GLIBCXX_TEMPLATE_ARGS
)>
596 #if _GLIBCXX_NUM_ARGS == 1
597 : public unary_function
<_T1
, _Res
>, private _Function_base
598 #elif _GLIBCXX_NUM_ARGS == 2
599 : public binary_function
<_T1
, _T2
, _Res
>, private _Function_base
601 : private _Function_base
606 * This class is used to implement the safe_bool idiom.
611 _Hidden_type
* _M_bool
;
616 * This typedef is used to implement the safe_bool idiom.
619 typedef _Hidden_type
* _Hidden_type::* _Safe_bool
;
621 typedef _Res
_Signature_type(_GLIBCXX_TEMPLATE_ARGS
);
626 typedef _Res result_type
;
628 // [3.7.2.1] construct/copy/destroy
631 * @brief Default construct creates an empty function call wrapper.
632 * @post @c !(bool)*this
634 function() : _Function_base() { }
637 * @brief Default construct creates an empty function call wrapper.
638 * @post @c !(bool)*this
640 function(_M_clear_type
*) : _Function_base() { }
643 * @brief %Function copy constructor.
644 * @param x A %function object with identical call signature.
645 * @pre @c (bool)*this == (bool)x
647 * The newly-created %function contains a copy of the target of @a
650 function(const function
& __x
);
653 * @brief Builds a %function that targets a copy of the incoming
655 * @param f A %function object that is callable with parameters of
656 * type @c T1, @c T2, ..., @c TN and returns a value convertible
659 * The newly-created %function object will target a copy of @a
660 * f. If @a f is @c reference_wrapper<F>, then this function
661 * object will contain a reference to the function object @c
662 * f.get(). If @a f is a NULL function pointer or NULL
663 * pointer-to-member, the newly-created object will be empty.
665 * If @a f is a non-NULL function pointer or an object of type @c
666 * reference_wrapper<F>, this function will not throw.
668 template<typename _Functor
>
669 function(_Functor __f
,
670 typename __enable_if
<_Useless
,
671 !is_integral
<_Functor
>::value
>::__type
675 * @brief %Function assignment operator.
676 * @param x A %function with identical call signature.
677 * @post @c (bool)*this == (bool)x
680 * The target of @a x is copied to @c *this. If @a x has no
681 * target, then @c *this will be empty.
683 * If @a x targets a function pointer or a reference to a function
684 * object, then this operation will not throw an exception.
686 function
& operator=(const function
& __x
)
688 function(__x
).swap(*this);
693 * @brief %Function assignment to zero.
694 * @post @c !(bool)*this
697 * The target of @a *this is deallocated, leaving it empty.
699 function
& operator=(_M_clear_type
*)
702 _M_manager(_M_functor
, _M_functor
, __destroy_functor
);
710 * @brief %Function assignment to a new target.
711 * @param f A %function object that is callable with parameters of
712 * type @c T1, @c T2, ..., @c TN and returns a value convertible
716 * This %function object wrapper will target a copy of @a
717 * f. If @a f is @c reference_wrapper<F>, then this function
718 * object will contain a reference to the function object @c
719 * f.get(). If @a f is a NULL function pointer or NULL
720 * pointer-to-member, @c this object will be empty.
722 * If @a f is a non-NULL function pointer or an object of type @c
723 * reference_wrapper<F>, this function will not throw.
725 template<typename _Functor
>
726 typename __enable_if
<function
&, !is_integral
<_Functor
>::value
>::__type
727 operator=(_Functor __f
)
729 function(__f
).swap(*this);
733 // [3.7.2.2] function modifiers
736 * @brief Swap the targets of two %function objects.
737 * @param f A %function with identical call signature.
739 * Swap the targets of @c this function object and @a f. This
740 * function will not throw an exception.
742 void swap(function
& __x
)
744 _Any_data __old_functor
= _M_functor
;
745 _M_functor
= __x
._M_functor
;
746 __x
._M_functor
= __old_functor
;
747 _Manager_type __old_manager
= _M_manager
;
748 _M_manager
= __x
._M_manager
;
749 __x
._M_manager
= __old_manager
;
750 _Invoker_type __old_invoker
= _M_invoker
;
751 _M_invoker
= __x
._M_invoker
;
752 __x
._M_invoker
= __old_invoker
;
755 // [3.7.2.3] function capacity
758 * @brief Determine if the %function wrapper has a target.
760 * @return @c true when this %function object contains a target,
761 * or @c false when it is empty.
763 * This function will not throw an exception.
765 operator _Safe_bool() const
773 return &_Hidden_type::_M_bool
;
777 // [3.7.2.4] function invocation
780 * @brief Invokes the function targeted by @c *this.
781 * @returns the result of the target.
782 * @throws bad_function_call when @c !(bool)*this
784 * The function call operator invokes the target function object
787 _Res
operator()(_GLIBCXX_PARAMS
) const;
789 // [3.7.2.5] function target access
791 * @brief Determine the type of the target of this function object
794 * @returns the type identifier of the target function object, or
795 * @c typeid(void) if @c !(bool)*this.
797 * This function will not throw an exception.
799 const type_info
& target_type() const;
802 * @brief Access the stored target function object.
804 * @return Returns a pointer to the stored target function object,
805 * if @c typeid(Functor).equals(target_type()); otherwise, a NULL
808 * This function will not throw an exception.
810 template<typename _Functor
> _Functor
* target();
815 template<typename _Functor
> const _Functor
* target() const;
818 // [3.7.2.6] undefined operators
819 template<typename _Function
>
820 void operator==(const function
<_Function
>&) const;
821 template<typename _Function
>
822 void operator!=(const function
<_Function
>&) const;
824 typedef _Res (*_Invoker_type
)(const _Any_data
& _GLIBCXX_COMMA
826 _Invoker_type _M_invoker
;
829 template<typename _Res _GLIBCXX_COMMA _GLIBCXX_TEMPLATE_PARAMS
>
830 function
<_Res(_GLIBCXX_TEMPLATE_ARGS
)>::function(const function
& __x
)
834 _M_invoker
= __x
._M_invoker
;
835 _M_manager
= __x
._M_manager
;
836 __x
._M_manager(_M_functor
, __x
._M_functor
, __clone_functor
);
840 template<typename _Res _GLIBCXX_COMMA _GLIBCXX_TEMPLATE_PARAMS
>
841 template<typename _Functor
>
842 function
<_Res(_GLIBCXX_TEMPLATE_ARGS
)>
843 ::function(_Functor __f
,
844 typename __enable_if
<_Useless
,
845 !is_integral
<_Functor
>::value
>::__type
)
848 typedef _Function_handler
<_Signature_type
, _Functor
> _My_handler
;
849 if (_My_handler::_M_not_empty_function(__f
)) {
850 _M_invoker
= &_My_handler::_M_invoke
;
851 _M_manager
= &_My_handler::_M_manager
;
852 _My_handler::_M_init_functor(_M_functor
, __f
);
856 template<typename _Res _GLIBCXX_COMMA _GLIBCXX_TEMPLATE_PARAMS
>
858 function
<_Res(_GLIBCXX_TEMPLATE_ARGS
)>::operator()(_GLIBCXX_PARAMS
) const
863 throw bad_function_call();
868 return _M_invoker(_M_functor _GLIBCXX_COMMA _GLIBCXX_ARGS
);
871 template<typename _Res _GLIBCXX_COMMA _GLIBCXX_TEMPLATE_PARAMS
>
873 function
<_Res(_GLIBCXX_TEMPLATE_ARGS
)>::target_type() const
877 _Any_data __typeinfo_result
;
878 _M_manager(__typeinfo_result
, _M_functor
, __get_type_info
);
879 return *__typeinfo_result
._M_access
<const type_info
*>();
887 template<typename _Res _GLIBCXX_COMMA _GLIBCXX_TEMPLATE_PARAMS
>
888 template<typename _Functor
>
890 function
<_Res(_GLIBCXX_TEMPLATE_ARGS
)>::target()
892 if (typeid(_Functor
) == target_type() && _M_manager
)
895 if (_M_manager(__ptr
, _M_functor
, __get_functor_ptr
)
896 && !is_const
<_Functor
>::value
)
899 return __ptr
._M_access
<_Functor
*>();
907 template<typename _Res _GLIBCXX_COMMA _GLIBCXX_TEMPLATE_PARAMS
>
908 template<typename _Functor
>
910 function
<_Res(_GLIBCXX_TEMPLATE_ARGS
)>::target() const
912 if (typeid(_Functor
) == target_type() && _M_manager
)
915 _M_manager(__ptr
, _M_functor
, __get_functor_ptr
);
916 return __ptr
._M_access
<const _Functor
*>();