1 // TR1 functional -*- C++ -*-
3 // Copyright (C) 2005, 2006 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.
38 _GLIBCXX_BEGIN_NAMESPACE(tr1
)
40 template<typename _Res _GLIBCXX_COMMA _GLIBCXX_TEMPLATE_PARAMS
>
41 struct _Weak_result_type_impl
<_Res(_GLIBCXX_TEMPLATE_ARGS
)>
43 typedef _Res result_type
;
46 template<typename _Res _GLIBCXX_COMMA _GLIBCXX_TEMPLATE_PARAMS
>
47 struct _Weak_result_type_impl
<_Res (&)(_GLIBCXX_TEMPLATE_ARGS
)>
49 typedef _Res result_type
;
52 template<typename _Res _GLIBCXX_COMMA _GLIBCXX_TEMPLATE_PARAMS
>
53 struct _Weak_result_type_impl
<_Res (*)(_GLIBCXX_TEMPLATE_ARGS
)>
55 typedef _Res result_type
;
58 #if _GLIBCXX_NUM_ARGS > 0
59 template<typename _Res
, typename _Class _GLIBCXX_COMMA_SHIFTED
60 _GLIBCXX_TEMPLATE_PARAMS_SHIFTED
>
61 struct _Weak_result_type_impl
<
62 _Res (_Class::*)(_GLIBCXX_TEMPLATE_ARGS_SHIFTED
)>
64 typedef _Res result_type
;
67 template<typename _Res
, typename _Class _GLIBCXX_COMMA_SHIFTED
68 _GLIBCXX_TEMPLATE_PARAMS_SHIFTED
>
69 struct _Weak_result_type_impl
<
70 _Res (_Class::*)(_GLIBCXX_TEMPLATE_ARGS_SHIFTED
) const>
72 typedef _Res result_type
;
75 template<typename _Res
, typename _Class _GLIBCXX_COMMA_SHIFTED
76 _GLIBCXX_TEMPLATE_PARAMS_SHIFTED
>
77 struct _Weak_result_type_impl
<
78 _Res (_Class::*)(_GLIBCXX_TEMPLATE_ARGS_SHIFTED
) volatile>
80 typedef _Res result_type
;
83 template<typename _Res
, typename _Class _GLIBCXX_COMMA_SHIFTED
84 _GLIBCXX_TEMPLATE_PARAMS_SHIFTED
>
85 struct _Weak_result_type_impl
<
86 _Res (_Class::*)(_GLIBCXX_TEMPLATE_ARGS_SHIFTED
) const volatile>
88 typedef _Res result_type
;
92 template<typename _Functor _GLIBCXX_COMMA _GLIBCXX_TEMPLATE_PARAMS
>
93 class result_of
<_Functor(_GLIBCXX_TEMPLATE_ARGS
)>
94 : public _Result_of_impl
<
95 _Has_result_type
<_Weak_result_type
<_Functor
> >::value
,
96 _Functor(_GLIBCXX_TEMPLATE_ARGS
)>
99 template<typename _Functor _GLIBCXX_COMMA _GLIBCXX_TEMPLATE_PARAMS
>
100 struct _Result_of_impl
<true, _Functor(_GLIBCXX_TEMPLATE_ARGS
)>
102 typedef typename _Weak_result_type
<_Functor
>::result_type type
;
105 template<typename _Functor _GLIBCXX_COMMA _GLIBCXX_TEMPLATE_PARAMS
>
106 struct _Result_of_impl
<false, _Functor(_GLIBCXX_TEMPLATE_ARGS
)>
108 #if _GLIBCXX_NUM_ARGS > 0
109 typedef typename _Functor
110 ::template result
<_Functor(_GLIBCXX_TEMPLATE_ARGS
)>::type type
;
118 * Invoke a function object, which may be either a member pointer or a
119 * function object. The first parameter will tell which.
122 template<typename _Functor _GLIBCXX_COMMA _GLIBCXX_TEMPLATE_PARAMS
>
124 typename
__gnu_cxx::__enable_if
<(!is_member_pointer
<_Functor
>::value
125 && !is_function
<_Functor
>::value
126 && !is_function
<typename remove_pointer
<_Functor
>::type
>::value
),
127 typename result_of
<_Functor(_GLIBCXX_TEMPLATE_ARGS
)>::type
>::__type
128 __invoke(_Functor
& __f _GLIBCXX_COMMA _GLIBCXX_REF_PARAMS
)
130 return __f(_GLIBCXX_ARGS
);
133 #if _GLIBCXX_NUM_ARGS > 0
134 template<typename _Functor _GLIBCXX_COMMA _GLIBCXX_TEMPLATE_PARAMS
>
136 typename
__gnu_cxx::__enable_if
<(is_member_pointer
<_Functor
>::value
137 && !is_function
<_Functor
>::value
138 && !is_function
<typename remove_pointer
<_Functor
>::type
>::value
),
139 typename result_of
<_Functor(_GLIBCXX_TEMPLATE_ARGS
)>::type
141 __invoke(_Functor
& __f _GLIBCXX_COMMA _GLIBCXX_REF_PARAMS
)
143 return mem_fn(__f
)(_GLIBCXX_ARGS
);
147 // To pick up function references (that will become function pointers)
148 template<typename _Functor _GLIBCXX_COMMA _GLIBCXX_TEMPLATE_PARAMS
>
150 typename
__gnu_cxx::__enable_if
<(is_pointer
<_Functor
>::value
151 && is_function
<typename remove_pointer
<_Functor
>::type
>::value
),
152 typename result_of
<_Functor(_GLIBCXX_TEMPLATE_ARGS
)>::type
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 __pf
) : __pmf(__pf
) { }
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 __pf
) : __pmf(__pf
) { }
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 __pf
) : __pmf(__pf
) { }
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 __pf
) : __pmf(__pf
) { }
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
);
399 } // anonymous namespace
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
__gnu_cxx::__enable_if
<!is_integral
<_Functor
>::value
, _Useless
>::__type
= _Useless());
673 * @brief %Function assignment operator.
674 * @param x A %function with identical call signature.
675 * @post @c (bool)*this == (bool)x
678 * The target of @a x is copied to @c *this. If @a x has no
679 * target, then @c *this will be empty.
681 * If @a x targets a function pointer or a reference to a function
682 * object, then this operation will not throw an exception.
684 function
& operator=(const function
& __x
)
686 function(__x
).swap(*this);
691 * @brief %Function assignment to zero.
692 * @post @c !(bool)*this
695 * The target of @a *this is deallocated, leaving it empty.
697 function
& operator=(_M_clear_type
*)
700 _M_manager(_M_functor
, _M_functor
, __destroy_functor
);
708 * @brief %Function assignment to a new target.
709 * @param f A %function object that is callable with parameters of
710 * type @c T1, @c T2, ..., @c TN and returns a value convertible
714 * This %function object wrapper will target a copy of @a
715 * f. If @a f is @c reference_wrapper<F>, then this function
716 * object will contain a reference to the function object @c
717 * f.get(). If @a f is a NULL function pointer or NULL
718 * pointer-to-member, @c this object will be empty.
720 * If @a f is a non-NULL function pointer or an object of type @c
721 * reference_wrapper<F>, this function will not throw.
723 template<typename _Functor
>
724 typename
__gnu_cxx::__enable_if
<!is_integral
<_Functor
>::value
, function
&>::__type
725 operator=(_Functor __f
)
727 function(__f
).swap(*this);
731 // [3.7.2.2] function modifiers
734 * @brief Swap the targets of two %function objects.
735 * @param f A %function with identical call signature.
737 * Swap the targets of @c this function object and @a f. This
738 * function will not throw an exception.
740 void swap(function
& __x
)
742 _Any_data __old_functor
= _M_functor
;
743 _M_functor
= __x
._M_functor
;
744 __x
._M_functor
= __old_functor
;
745 _Manager_type __old_manager
= _M_manager
;
746 _M_manager
= __x
._M_manager
;
747 __x
._M_manager
= __old_manager
;
748 _Invoker_type __old_invoker
= _M_invoker
;
749 _M_invoker
= __x
._M_invoker
;
750 __x
._M_invoker
= __old_invoker
;
753 // [3.7.2.3] function capacity
756 * @brief Determine if the %function wrapper has a target.
758 * @return @c true when this %function object contains a target,
759 * or @c false when it is empty.
761 * This function will not throw an exception.
763 operator _Safe_bool() const
771 return &_Hidden_type::_M_bool
;
775 // [3.7.2.4] function invocation
778 * @brief Invokes the function targeted by @c *this.
779 * @returns the result of the target.
780 * @throws bad_function_call when @c !(bool)*this
782 * The function call operator invokes the target function object
785 _Res
operator()(_GLIBCXX_PARAMS
) const;
787 // [3.7.2.5] function target access
789 * @brief Determine the type of the target of this function object
792 * @returns the type identifier of the target function object, or
793 * @c typeid(void) if @c !(bool)*this.
795 * This function will not throw an exception.
797 const type_info
& target_type() const;
800 * @brief Access the stored target function object.
802 * @return Returns a pointer to the stored target function object,
803 * if @c typeid(Functor).equals(target_type()); otherwise, a NULL
806 * This function will not throw an exception.
808 template<typename _Functor
> _Functor
* target();
813 template<typename _Functor
> const _Functor
* target() const;
816 // [3.7.2.6] undefined operators
817 template<typename _Function
>
818 void operator==(const function
<_Function
>&) const;
819 template<typename _Function
>
820 void operator!=(const function
<_Function
>&) const;
822 typedef _Res (*_Invoker_type
)(const _Any_data
& _GLIBCXX_COMMA
824 _Invoker_type _M_invoker
;
827 template<typename _Res _GLIBCXX_COMMA _GLIBCXX_TEMPLATE_PARAMS
>
828 function
<_Res(_GLIBCXX_TEMPLATE_ARGS
)>::function(const function
& __x
)
832 _M_invoker
= __x
._M_invoker
;
833 _M_manager
= __x
._M_manager
;
834 __x
._M_manager(_M_functor
, __x
._M_functor
, __clone_functor
);
838 template<typename _Res _GLIBCXX_COMMA _GLIBCXX_TEMPLATE_PARAMS
>
839 template<typename _Functor
>
840 function
<_Res(_GLIBCXX_TEMPLATE_ARGS
)>
841 ::function(_Functor __f
,
842 typename
__gnu_cxx::__enable_if
<!is_integral
<_Functor
>::value
, _Useless
>::__type
)
845 typedef _Function_handler
<_Signature_type
, _Functor
> _My_handler
;
846 if (_My_handler::_M_not_empty_function(__f
)) {
847 _M_invoker
= &_My_handler::_M_invoke
;
848 _M_manager
= &_My_handler::_M_manager
;
849 _My_handler::_M_init_functor(_M_functor
, __f
);
853 template<typename _Res _GLIBCXX_COMMA _GLIBCXX_TEMPLATE_PARAMS
>
855 function
<_Res(_GLIBCXX_TEMPLATE_ARGS
)>::operator()(_GLIBCXX_PARAMS
) const
860 throw bad_function_call();
865 return _M_invoker(_M_functor _GLIBCXX_COMMA _GLIBCXX_ARGS
);
868 template<typename _Res _GLIBCXX_COMMA _GLIBCXX_TEMPLATE_PARAMS
>
870 function
<_Res(_GLIBCXX_TEMPLATE_ARGS
)>::target_type() const
874 _Any_data __typeinfo_result
;
875 _M_manager(__typeinfo_result
, _M_functor
, __get_type_info
);
876 return *__typeinfo_result
._M_access
<const type_info
*>();
884 template<typename _Res _GLIBCXX_COMMA _GLIBCXX_TEMPLATE_PARAMS
>
885 template<typename _Functor
>
887 function
<_Res(_GLIBCXX_TEMPLATE_ARGS
)>::target()
889 if (typeid(_Functor
) == target_type() && _M_manager
)
892 if (_M_manager(__ptr
, _M_functor
, __get_functor_ptr
)
893 && !is_const
<_Functor
>::value
)
896 return __ptr
._M_access
<_Functor
*>();
904 template<typename _Res _GLIBCXX_COMMA _GLIBCXX_TEMPLATE_PARAMS
>
905 template<typename _Functor
>
907 function
<_Res(_GLIBCXX_TEMPLATE_ARGS
)>::target() const
909 if (typeid(_Functor
) == target_type() && _M_manager
)
912 _M_manager(__ptr
, _M_functor
, __get_functor_ptr
);
913 return __ptr
._M_access
<const _Functor
*>();
921 _GLIBCXX_END_NAMESPACE