Remove old autovect-branch by moving to "dead" directory.
[official-gcc.git] / old-autovect-branch / libstdc++-v3 / include / tr1 / functional_iterate.h
blob0b08a6969a7b5cee1d9d99e0dae73a51012c8870
1 // TR1 functional -*- C++ -*-
3 // Copyright (C) 2005 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 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;
86 #endif
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)>
93 { };
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;
107 #else
108 typedef void type;
109 #endif
113 * @if maint
114 * Invoke a function object, which may be either a member pointer or a
115 * function object. The first parameter will tell which.
116 * @endif
118 template<typename _Functor _GLIBCXX_COMMA _GLIBCXX_TEMPLATE_PARAMS>
119 inline
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)
125 >::__type
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>
133 inline
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)
139 >::__type
140 __invoke(_Functor& __f _GLIBCXX_COMMA _GLIBCXX_REF_PARAMS)
142 return mem_fn(__f)(_GLIBCXX_ARGS);
144 #endif
146 // To pick up function references (that will become function pointers)
147 template<typename _Functor _GLIBCXX_COMMA _GLIBCXX_TEMPLATE_PARAMS>
148 inline
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)
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 __pmf) : __pmf(__pmf) { }
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 __pmf) : __pmf(__pmf) { }
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 __pmf) : __pmf(__pmf) { }
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 __pmf) : __pmf(__pmf) { }
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);
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 __enable_if<_Useless,
671 !is_integral<_Functor>::value>::__type
672 = _Useless());
675 * @brief %Function assignment operator.
676 * @param x A %function with identical call signature.
677 * @post @c (bool)*this == (bool)x
678 * @returns @c *this
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);
689 return *this;
693 * @brief %Function assignment to zero.
694 * @post @c !(bool)*this
695 * @returns @c *this
697 * The target of @a *this is deallocated, leaving it empty.
699 function& operator=(_M_clear_type*)
701 if (_M_manager) {
702 _M_manager(_M_functor, _M_functor, __destroy_functor);
703 _M_manager = 0;
704 _M_invoker = 0;
706 return *this;
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
713 * to @c Res.
714 * @return @c *this
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);
730 return *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
767 if (_M_empty())
769 return 0;
771 else
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
785 * stored by @c this.
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
792 * wrapper.
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
806 * pointer.
808 * This function will not throw an exception.
810 template<typename _Functor> _Functor* target();
813 * @overload
815 template<typename _Functor> const _Functor* target() const;
817 private:
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
825 _GLIBCXX_PARAMS);
826 _Invoker_type _M_invoker;
829 template<typename _Res _GLIBCXX_COMMA _GLIBCXX_TEMPLATE_PARAMS>
830 function<_Res(_GLIBCXX_TEMPLATE_ARGS)>::function(const function& __x)
831 : _Function_base()
833 if (__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)
846 : _Function_base()
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>
857 _Res
858 function<_Res(_GLIBCXX_TEMPLATE_ARGS)>::operator()(_GLIBCXX_PARAMS) const
860 if (_M_empty())
862 #if __EXCEPTIONS
863 throw bad_function_call();
864 #else
865 std::abort();
866 #endif
868 return _M_invoker(_M_functor _GLIBCXX_COMMA _GLIBCXX_ARGS);
871 template<typename _Res _GLIBCXX_COMMA _GLIBCXX_TEMPLATE_PARAMS>
872 const type_info&
873 function<_Res(_GLIBCXX_TEMPLATE_ARGS)>::target_type() const
875 if (_M_manager)
877 _Any_data __typeinfo_result;
878 _M_manager(__typeinfo_result, _M_functor, __get_type_info);
879 return *__typeinfo_result._M_access<const type_info*>();
881 else
883 return typeid(void);
887 template<typename _Res _GLIBCXX_COMMA _GLIBCXX_TEMPLATE_PARAMS>
888 template<typename _Functor>
889 _Functor*
890 function<_Res(_GLIBCXX_TEMPLATE_ARGS)>::target()
892 if (typeid(_Functor) == target_type() && _M_manager)
894 _Any_data __ptr;
895 if (_M_manager(__ptr, _M_functor, __get_functor_ptr)
896 && !is_const<_Functor>::value)
897 return 0;
898 else
899 return __ptr._M_access<_Functor*>();
901 else
903 return 0;
907 template<typename _Res _GLIBCXX_COMMA _GLIBCXX_TEMPLATE_PARAMS>
908 template<typename _Functor>
909 const _Functor*
910 function<_Res(_GLIBCXX_TEMPLATE_ARGS)>::target() const
912 if (typeid(_Functor) == target_type() && _M_manager)
914 _Any_data __ptr;
915 _M_manager(__ptr, _M_functor, __get_functor_ptr);
916 return __ptr._M_access<const _Functor*>();
918 else
920 return 0;