2006-11-29 Benjamin Kosnik <bkoz@redhat.com>
[official-gcc.git] / libstdc++-v3 / include / tr1 / functional_iterate.h
blob3d6cc8c5c1a6d4c172673f8a9f0c85f61f09ce79
1 // TR1 functional -*- C++ -*-
3 // Copyright (C) 2005, 2006 Free Software Foundation, Inc.
4 // Written by Douglas Gregor <doug.gregor -at- gmail.com>
5 //
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)
10 // any later version.
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,
20 // USA.
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 namespace std
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;
90 #endif
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)>
97 { };
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;
111 #else
112 typedef void type;
113 #endif
117 * @if maint
118 * Invoke a function object, which may be either a member pointer or a
119 * function object. The first parameter will tell which.
120 * @endif
122 template<typename _Functor _GLIBCXX_COMMA _GLIBCXX_TEMPLATE_PARAMS>
123 inline
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>
135 inline
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
140 >::__type
141 __invoke(_Functor& __f _GLIBCXX_COMMA _GLIBCXX_REF_PARAMS)
143 return mem_fn(__f)(_GLIBCXX_ARGS);
145 #endif
147 // To pick up function references (that will become function pointers)
148 template<typename _Functor _GLIBCXX_COMMA _GLIBCXX_TEMPLATE_PARAMS>
149 inline
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
153 >::__type
154 __invoke(_Functor __f _GLIBCXX_COMMA _GLIBCXX_REF_PARAMS)
156 return __f(_GLIBCXX_ARGS);
160 * @if maint
161 * Implementation of reference_wrapper::operator()
162 * @endif
164 #if _GLIBCXX_NUM_ARGS > 0
165 template<typename _Tp>
166 template<_GLIBCXX_TEMPLATE_PARAMS>
167 typename result_of<
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);
173 #endif
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>
183 #endif
185 typedef _Res (_Class::*_Functor)(_GLIBCXX_TEMPLATE_ARGS_SHIFTED);
187 template<typename _Tp>
188 _Res
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>
194 _Res
195 _M_call(_Tp& __ptr, const volatile void * _GLIBCXX_COMMA_SHIFTED
196 _GLIBCXX_PARAMS_SHIFTED) const
197 { return ((*__ptr).*__pmf)(_GLIBCXX_ARGS_SHIFTED); }
199 public:
200 typedef _Res result_type;
202 explicit _Mem_fn(_Functor __pf) : __pmf(__pf) { }
204 // Handle objects
205 _Res
206 operator()(_Class& __object _GLIBCXX_COMMA_SHIFTED
207 _GLIBCXX_PARAMS_SHIFTED) const
208 { return (__object.*__pmf)(_GLIBCXX_ARGS_SHIFTED); }
210 // Handle pointers
211 _Res
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>
218 _Res
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);
226 private:
227 _Functor __pmf;
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>
237 #endif
239 typedef _Res (_Class::*_Functor)(_GLIBCXX_TEMPLATE_ARGS_SHIFTED) const;
241 template<typename _Tp>
242 _Res
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>
248 _Res
249 _M_call(_Tp& __ptr, const volatile void * _GLIBCXX_COMMA_SHIFTED
250 _GLIBCXX_PARAMS_SHIFTED) const
251 { return ((*__ptr).*__pmf)(_GLIBCXX_ARGS_SHIFTED); }
253 public:
254 typedef _Res result_type;
256 explicit _Mem_fn(_Functor __pf) : __pmf(__pf) { }
258 // Handle objects
259 _Res
260 operator()(const _Class& __object _GLIBCXX_COMMA_SHIFTED
261 _GLIBCXX_PARAMS_SHIFTED) const
262 { return (__object.*__pmf)(_GLIBCXX_ARGS_SHIFTED); }
264 // Handle pointers
265 _Res
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>
272 _Res
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);
280 private:
281 _Functor __pmf;
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>
291 #endif
293 typedef _Res (_Class::*_Functor)(_GLIBCXX_TEMPLATE_ARGS_SHIFTED) volatile;
295 template<typename _Tp>
296 _Res
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>
302 _Res
303 _M_call(_Tp& __ptr, const volatile void * _GLIBCXX_COMMA_SHIFTED
304 _GLIBCXX_PARAMS_SHIFTED) const
305 { return ((*__ptr).*__pmf)(_GLIBCXX_ARGS_SHIFTED); }
307 public:
308 typedef _Res result_type;
310 explicit _Mem_fn(_Functor __pf) : __pmf(__pf) { }
312 // Handle objects
313 _Res
314 operator()(volatile _Class& __object _GLIBCXX_COMMA_SHIFTED
315 _GLIBCXX_PARAMS_SHIFTED) const
316 { return (__object.*__pmf)(_GLIBCXX_ARGS_SHIFTED); }
318 // Handle pointers
319 _Res
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>
326 _Res
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);
333 private:
334 _Functor __pmf;
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>
344 #endif
346 typedef _Res (_Class::*_Functor)(_GLIBCXX_TEMPLATE_ARGS_SHIFTED)
347 const volatile;
349 template<typename _Tp>
350 _Res
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>
356 _Res
357 _M_call(_Tp& __ptr, const volatile void * _GLIBCXX_COMMA_SHIFTED
358 _GLIBCXX_PARAMS_SHIFTED) const
359 { return ((*__ptr).*__pmf)(_GLIBCXX_ARGS_SHIFTED); }
361 public:
362 typedef _Res result_type;
364 explicit _Mem_fn(_Functor __pf) : __pmf(__pf) { }
366 // Handle objects
367 _Res
368 operator()(const volatile _Class& __object _GLIBCXX_COMMA_SHIFTED
369 _GLIBCXX_PARAMS_SHIFTED) const
370 { return (__object.*__pmf)(_GLIBCXX_ARGS_SHIFTED); }
372 // Handle pointers
373 _Res
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>
380 _Res
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);
388 private:
389 _Functor __pmf;
391 #endif
393 #if _GLIBCXX_NUM_ARGS > 0
394 namespace placeholders
396 namespace
398 _Placeholder<_GLIBCXX_NUM_ARGS> _GLIBCXX_JOIN(_,_GLIBCXX_NUM_ARGS);
399 } // anonymous namespace
401 #endif
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;
409 _Functor _M_f;
410 _GLIBCXX_BIND_MEMBERS
412 public:
413 #if _GLIBCXX_NUM_ARGS == 0
414 explicit
415 #endif
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)>
428 _Functor _M_f;
429 _GLIBCXX_BIND_MEMBERS
431 public:
432 typedef _Result result_type;
434 #if _GLIBCXX_NUM_ARGS == 0
435 explicit
436 #endif
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>
449 inline
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>
463 inline
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)>
472 __result_type;
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;
484 public:
485 static _Res
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;
498 public:
499 static void
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;
514 public:
515 static _Res
516 _M_invoke(const _Any_data& __functor _GLIBCXX_COMMA _GLIBCXX_PARAMS)
518 return __callable_functor(**_Base::_M_get_pointer(__functor))
519 (_GLIBCXX_ARGS);
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;
530 public:
531 static void
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::*>
544 _Base;
546 public:
547 static _Res
548 _M_invoke(const _Any_data& __functor _GLIBCXX_COMMA _GLIBCXX_PARAMS)
550 return std::tr1::mem_fn(_Base::_M_get_pointer(__functor)->__value)
551 (_GLIBCXX_ARGS);
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;
565 public:
566 static bool
567 _M_manager(_Any_data& __dest, const _Any_data& __source,
568 _Manager_operation __op)
570 switch (__op) {
571 case __get_type_info:
572 __dest._M_access<const type_info*>() = &typeid(_Functor);
573 break;
575 case __get_functor_ptr:
576 __dest._M_access<_Functor*>() =
577 &_Base::_M_get_pointer(__source)->__value;
578 break;
580 default:
581 _Base::_M_manager(__dest, __source, __op);
583 return false;
586 static void
587 _M_invoke(const _Any_data& __functor _GLIBCXX_COMMA _GLIBCXX_PARAMS)
589 std::tr1::mem_fn(_Base::_M_get_pointer(__functor)->__value)
590 (_GLIBCXX_ARGS);
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
600 #else
601 : private _Function_base
602 #endif
605 * @if maint
606 * This class is used to implement the safe_bool idiom.
607 * @endif
609 struct _Hidden_type
611 _Hidden_type* _M_bool;
615 * @if maint
616 * This typedef is used to implement the safe_bool idiom.
617 * @endif
619 typedef _Hidden_type* _Hidden_type::* _Safe_bool;
621 typedef _Res _Signature_type(_GLIBCXX_TEMPLATE_ARGS);
623 struct _Useless {};
625 public:
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
648 * x (if it has one).
650 function(const function& __x);
653 * @brief Builds a %function that targets a copy of the incoming
654 * function object.
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
657 * to @c Res.
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
676 * @returns @c *this
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);
687 return *this;
691 * @brief %Function assignment to zero.
692 * @post @c !(bool)*this
693 * @returns @c *this
695 * The target of @a *this is deallocated, leaving it empty.
697 function& operator=(_M_clear_type*)
699 if (_M_manager) {
700 _M_manager(_M_functor, _M_functor, __destroy_functor);
701 _M_manager = 0;
702 _M_invoker = 0;
704 return *this;
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
711 * to @c Res.
712 * @return @c *this
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);
728 return *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
765 if (_M_empty())
767 return 0;
769 else
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
783 * stored by @c this.
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
790 * wrapper.
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
804 * pointer.
806 * This function will not throw an exception.
808 template<typename _Functor> _Functor* target();
811 * @overload
813 template<typename _Functor> const _Functor* target() const;
815 private:
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
823 _GLIBCXX_PARAMS);
824 _Invoker_type _M_invoker;
827 template<typename _Res _GLIBCXX_COMMA _GLIBCXX_TEMPLATE_PARAMS>
828 function<_Res(_GLIBCXX_TEMPLATE_ARGS)>::function(const function& __x)
829 : _Function_base()
831 if (__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)
843 : _Function_base()
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>
854 _Res
855 function<_Res(_GLIBCXX_TEMPLATE_ARGS)>::operator()(_GLIBCXX_PARAMS) const
857 if (_M_empty())
859 #if __EXCEPTIONS
860 throw bad_function_call();
861 #else
862 std::abort();
863 #endif
865 return _M_invoker(_M_functor _GLIBCXX_COMMA _GLIBCXX_ARGS);
868 template<typename _Res _GLIBCXX_COMMA _GLIBCXX_TEMPLATE_PARAMS>
869 const type_info&
870 function<_Res(_GLIBCXX_TEMPLATE_ARGS)>::target_type() const
872 if (_M_manager)
874 _Any_data __typeinfo_result;
875 _M_manager(__typeinfo_result, _M_functor, __get_type_info);
876 return *__typeinfo_result._M_access<const type_info*>();
878 else
880 return typeid(void);
884 template<typename _Res _GLIBCXX_COMMA _GLIBCXX_TEMPLATE_PARAMS>
885 template<typename _Functor>
886 _Functor*
887 function<_Res(_GLIBCXX_TEMPLATE_ARGS)>::target()
889 if (typeid(_Functor) == target_type() && _M_manager)
891 _Any_data __ptr;
892 if (_M_manager(__ptr, _M_functor, __get_functor_ptr)
893 && !is_const<_Functor>::value)
894 return 0;
895 else
896 return __ptr._M_access<_Functor*>();
898 else
900 return 0;
904 template<typename _Res _GLIBCXX_COMMA _GLIBCXX_TEMPLATE_PARAMS>
905 template<typename _Functor>
906 const _Functor*
907 function<_Res(_GLIBCXX_TEMPLATE_ARGS)>::target() const
909 if (typeid(_Functor) == target_type() && _M_manager)
911 _Any_data __ptr;
912 _M_manager(__ptr, _M_functor, __get_functor_ptr);
913 return __ptr._M_access<const _Functor*>();
915 else
917 return 0;
921 _GLIBCXX_END_NAMESPACE