]> CyberLeo.Net >> Repos - FreeBSD/releng/9.2.git/blob - contrib/libstdc++/include/tr1/functional_iterate.h
- Copy stable/9 to releng/9.2 as part of the 9.2-RELEASE cycle.
[FreeBSD/releng/9.2.git] / contrib / libstdc++ / include / tr1 / functional_iterate.h
1 // TR1 functional -*- C++ -*-
2
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.
11
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.
16
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.
21
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.
30
31 /** @file tr1/functional_iterate.h
32  *  This is an internal header file, included by other library headers.
33  *  You should not attempt to use it directly.
34  */
35
36 namespace std
37 {
38 _GLIBCXX_BEGIN_NAMESPACE(tr1)
39
40 template<typename _Res _GLIBCXX_COMMA _GLIBCXX_TEMPLATE_PARAMS>
41   struct _Weak_result_type_impl<_Res(_GLIBCXX_TEMPLATE_ARGS)>
42   {
43     typedef _Res result_type;
44   };
45
46 template<typename _Res _GLIBCXX_COMMA _GLIBCXX_TEMPLATE_PARAMS>
47   struct _Weak_result_type_impl<_Res (&)(_GLIBCXX_TEMPLATE_ARGS)>
48   {
49     typedef _Res result_type;
50   };
51
52 template<typename _Res _GLIBCXX_COMMA _GLIBCXX_TEMPLATE_PARAMS>
53   struct _Weak_result_type_impl<_Res (*)(_GLIBCXX_TEMPLATE_ARGS)>
54   {
55     typedef _Res result_type;
56   };
57
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)>
63   {
64     typedef _Res result_type;
65   };
66
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>
71   {
72     typedef _Res result_type;
73   };
74
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>
79   {
80     typedef _Res result_type;
81   };
82
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>
87   {
88     typedef _Res result_type;
89   };
90 #endif
91
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   { };
98
99 template<typename _Functor _GLIBCXX_COMMA _GLIBCXX_TEMPLATE_PARAMS>
100   struct _Result_of_impl<true, _Functor(_GLIBCXX_TEMPLATE_ARGS)>
101   {
102     typedef typename _Weak_result_type<_Functor>::result_type type;
103   };
104
105 template<typename _Functor _GLIBCXX_COMMA _GLIBCXX_TEMPLATE_PARAMS>
106   struct _Result_of_impl<false, _Functor(_GLIBCXX_TEMPLATE_ARGS)>
107   {
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
114   };
115
116 /**
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
121  */
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)
129   {
130     return __f(_GLIBCXX_ARGS);
131   }
132
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)
142   {
143     return mem_fn(__f)(_GLIBCXX_ARGS);
144   }
145 #endif
146
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)
155   {
156     return __f(_GLIBCXX_ARGS);
157   }
158
159 /**
160  * @if maint
161  * Implementation of reference_wrapper::operator()
162  * @endif
163 */
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
170   {
171     return __invoke(get(), _GLIBCXX_ARGS);
172   }
173 #endif
174
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
184   {
185     typedef _Res (_Class::*_Functor)(_GLIBCXX_TEMPLATE_ARGS_SHIFTED);
186
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); }
192
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); }
198
199   public:
200     typedef _Res result_type;
201
202     explicit _Mem_fn(_Functor __pf) : __pmf(__pf) { }
203
204     // Handle objects
205     _Res
206     operator()(_Class& __object _GLIBCXX_COMMA_SHIFTED
207                _GLIBCXX_PARAMS_SHIFTED) const
208     { return (__object.*__pmf)(_GLIBCXX_ARGS_SHIFTED); }
209
210     // Handle pointers
211     _Res
212     operator()(_Class* __object _GLIBCXX_COMMA_SHIFTED
213                _GLIBCXX_PARAMS_SHIFTED) const
214     { return (__object->*__pmf)(_GLIBCXX_ARGS_SHIFTED); }
215
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
221       {
222         return _M_call(__object, &__object _GLIBCXX_COMMA_SHIFTED
223                        _GLIBCXX_ARGS_SHIFTED);
224       }
225
226   private:
227     _Functor __pmf;
228   };
229
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
238   {
239     typedef _Res (_Class::*_Functor)(_GLIBCXX_TEMPLATE_ARGS_SHIFTED) const;
240
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); }
246
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); }
252
253   public:
254     typedef _Res result_type;
255
256     explicit _Mem_fn(_Functor __pf) : __pmf(__pf) { }
257
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); }
263
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); }
269
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
275       {
276         return _M_call(__object, &__object _GLIBCXX_COMMA_SHIFTED
277                        _GLIBCXX_ARGS_SHIFTED);
278       }
279
280   private:
281     _Functor __pmf;
282   };
283
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
292   {
293     typedef _Res (_Class::*_Functor)(_GLIBCXX_TEMPLATE_ARGS_SHIFTED) volatile;
294
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); }
300
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); }
306
307   public:
308     typedef _Res result_type;
309
310     explicit _Mem_fn(_Functor __pf) : __pmf(__pf) { }
311
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); }
317
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); }
323
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
329       {
330         return _M_call(__object, &__object _GLIBCXX_COMMA_SHIFTED
331                        _GLIBCXX_ARGS_SHIFTED);
332       }
333   private:
334     _Functor __pmf;
335   };
336
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
345   {
346     typedef _Res (_Class::*_Functor)(_GLIBCXX_TEMPLATE_ARGS_SHIFTED)
347               const volatile;
348
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); }
354
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); }
360
361   public:
362     typedef _Res result_type;
363
364     explicit _Mem_fn(_Functor __pf) : __pmf(__pf) { }
365
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); }
371
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); }
377
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
383       {
384         return _M_call(__object, &__object _GLIBCXX_COMMA_SHIFTED
385                        _GLIBCXX_ARGS_SHIFTED);
386       }
387
388   private:
389     _Functor __pmf;
390   };
391 #endif
392
393 #if _GLIBCXX_NUM_ARGS > 0
394 namespace placeholders
395 {
396 namespace
397 {
398    _Placeholder<_GLIBCXX_NUM_ARGS> _GLIBCXX_JOIN(_,_GLIBCXX_NUM_ARGS);
399 } // anonymous namespace
400 }
401 #endif
402
403 template<typename _Functor _GLIBCXX_COMMA _GLIBCXX_TEMPLATE_PARAMS>
404 class _Bind<_Functor(_GLIBCXX_TEMPLATE_ARGS)>
405   : public _Weak_result_type<_Functor>
406 {
407   typedef _Bind __self_type;
408
409   _Functor _M_f;
410   _GLIBCXX_BIND_MEMBERS
411
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 { }
418
419 #define _GLIBCXX_BIND_REPEAT_HEADER <tr1/bind_iterate.h>
420 #include <tr1/bind_repeat.h>
421 #undef _GLIBCXX_BIND_REPEAT_HEADER
422 };
423
424 template<typename _Result, typename _Functor
425          _GLIBCXX_COMMA _GLIBCXX_TEMPLATE_PARAMS>
426 class _Bind_result<_Result, _Functor(_GLIBCXX_TEMPLATE_ARGS)>
427 {
428   _Functor _M_f;
429   _GLIBCXX_BIND_MEMBERS
430
431  public:
432   typedef _Result result_type;
433
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 { }
439
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
445 };
446
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)
453 {
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);
459 }
460
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)
468 {
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);
475 }
476
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>
481 {
482   typedef _Function_base::_Base_manager<_Functor> _Base;
483
484  public:
485   static _Res
486   _M_invoke(const _Any_data& __functor _GLIBCXX_COMMA _GLIBCXX_PARAMS)
487   {
488     return (*_Base::_M_get_pointer(__functor))(_GLIBCXX_ARGS);
489   }
490 };
491
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>
495 {
496   typedef _Function_base::_Base_manager<_Functor> _Base;
497
498  public:
499   static void
500   _M_invoke(const _Any_data& __functor _GLIBCXX_COMMA _GLIBCXX_PARAMS)
501   {
502     (*_Base::_M_get_pointer(__functor))(_GLIBCXX_ARGS);
503   }
504 };
505
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>
511 {
512   typedef _Function_base::_Ref_manager<_Functor> _Base;
513
514  public:
515   static _Res
516   _M_invoke(const _Any_data& __functor _GLIBCXX_COMMA _GLIBCXX_PARAMS)
517   {
518     return __callable_functor(**_Base::_M_get_pointer(__functor))
519              (_GLIBCXX_ARGS);
520   }
521 };
522
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>
527 {
528   typedef _Function_base::_Ref_manager<_Functor> _Base;
529
530  public:
531   static void
532   _M_invoke(const _Any_data& __functor _GLIBCXX_COMMA _GLIBCXX_PARAMS)
533   {
534     __callable_functor(**_Base::_M_get_pointer(__functor))(_GLIBCXX_ARGS);
535   }
536 };
537
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::*>
542 {
543   typedef _Function_handler<void(_GLIBCXX_TEMPLATE_ARGS), _Member _Class::*>
544     _Base;
545
546  public:
547   static _Res
548   _M_invoke(const _Any_data& __functor _GLIBCXX_COMMA _GLIBCXX_PARAMS)
549   {
550     return std::tr1::mem_fn(_Base::_M_get_pointer(__functor)->__value)
551              (_GLIBCXX_ARGS);
552   }
553 };
554
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::* > >
560 {
561   typedef _Member _Class::* _Functor;
562   typedef _Simple_type_wrapper< _Functor > _Wrapper;
563   typedef _Function_base::_Base_manager<_Wrapper> _Base;
564
565  public:
566   static bool
567   _M_manager(_Any_data& __dest, const _Any_data& __source,
568              _Manager_operation __op)
569   {
570     switch (__op) {
571     case __get_type_info:
572       __dest._M_access<const type_info*>() = &typeid(_Functor);
573       break;
574
575     case __get_functor_ptr:
576       __dest._M_access<_Functor*>() =
577         &_Base::_M_get_pointer(__source)->__value;
578       break;
579
580     default:
581       _Base::_M_manager(__dest, __source, __op);
582     }
583     return false;
584   }
585
586   static void
587   _M_invoke(const _Any_data& __functor _GLIBCXX_COMMA _GLIBCXX_PARAMS)
588   {
589     std::tr1::mem_fn(_Base::_M_get_pointer(__functor)->__value)
590       (_GLIBCXX_ARGS);
591   }
592 };
593
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
603 {
604   /**
605    *  @if maint
606    *  This class is used to implement the safe_bool idiom.
607    *  @endif
608    */
609   struct _Hidden_type
610   {
611     _Hidden_type* _M_bool;
612   };
613
614   /**
615    *  @if maint
616    *  This typedef is used to implement the safe_bool idiom.
617    *  @endif
618    */
619   typedef _Hidden_type* _Hidden_type::* _Safe_bool;
620
621   typedef _Res _Signature_type(_GLIBCXX_TEMPLATE_ARGS);
622
623   struct _Useless {};
624
625  public:
626   typedef _Res result_type;
627
628   // [3.7.2.1] construct/copy/destroy
629
630   /**
631    *  @brief Default construct creates an empty function call wrapper.
632    *  @post @c !(bool)*this
633    */
634   function() : _Function_base() { }
635
636   /**
637    *  @brief Default construct creates an empty function call wrapper.
638    *  @post @c !(bool)*this
639    */
640   function(_M_clear_type*) : _Function_base() { }
641
642   /**
643    *  @brief %Function copy constructor.
644    *  @param x A %function object with identical call signature.
645    *  @pre @c (bool)*this == (bool)x
646    *
647    *  The newly-created %function contains a copy of the target of @a
648    *  x (if it has one).
649    */
650   function(const function& __x);
651
652   /**
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.
658    *
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.
664    *
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.
667    */
668   template<typename _Functor>
669     function(_Functor __f,
670              typename __gnu_cxx::__enable_if<!is_integral<_Functor>::value, _Useless>::__type = _Useless());
671
672   /**
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
677    *
678    *  The target of @a x is copied to @c *this. If @a x has no
679    *  target, then @c *this will be empty.
680    *
681    *  If @a x targets a function pointer or a reference to a function
682    *  object, then this operation will not throw an exception.
683    */
684   function& operator=(const function& __x)
685     {
686       function(__x).swap(*this);
687       return *this;
688     }
689
690   /**
691    *  @brief %Function assignment to zero.
692    *  @post @c !(bool)*this
693    *  @returns @c *this
694    *
695    *  The target of @a *this is deallocated, leaving it empty.
696    */
697   function& operator=(_M_clear_type*)
698     {
699       if (_M_manager) {
700         _M_manager(_M_functor, _M_functor, __destroy_functor);
701         _M_manager = 0;
702         _M_invoker = 0;
703       }
704       return *this;
705     }
706
707   /**
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
713    *
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.
719    *
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.
722    */
723   template<typename _Functor>
724     typename __gnu_cxx::__enable_if<!is_integral<_Functor>::value, function&>::__type
725     operator=(_Functor __f)
726     {
727       function(__f).swap(*this);
728       return *this;
729     }
730
731   // [3.7.2.2] function modifiers
732
733   /**
734    *  @brief Swap the targets of two %function objects.
735    *  @param f A %function with identical call signature.
736    *
737    *  Swap the targets of @c this function object and @a f. This
738    *  function will not throw an exception.
739    */
740   void swap(function& __x)
741   {
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;
751   }
752
753   // [3.7.2.3] function capacity
754
755   /**
756    *  @brief Determine if the %function wrapper has a target.
757    *
758    *  @return @c true when this %function object contains a target,
759    *  or @c false when it is empty.
760    *
761    *  This function will not throw an exception.
762    */
763   operator _Safe_bool() const
764     {
765       if (_M_empty())
766         {
767           return 0;
768         }
769       else
770         {
771           return &_Hidden_type::_M_bool;
772         }
773     }
774
775   // [3.7.2.4] function invocation
776
777   /**
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
781    *
782    *  The function call operator invokes the target function object
783    *  stored by @c this.
784    */
785   _Res operator()(_GLIBCXX_PARAMS) const;
786
787   // [3.7.2.5] function target access
788   /**
789    *  @brief Determine the type of the target of this function object
790    *  wrapper.
791    *
792    *  @returns the type identifier of the target function object, or
793    *  @c typeid(void) if @c !(bool)*this.
794    *
795    *  This function will not throw an exception.
796    */
797   const type_info& target_type() const;
798
799   /**
800    *  @brief Access the stored target function object.
801    *
802    *  @return Returns a pointer to the stored target function object,
803    *  if @c typeid(Functor).equals(target_type()); otherwise, a NULL
804    *  pointer.
805    *
806    * This function will not throw an exception.
807    */
808   template<typename _Functor>       _Functor* target();
809
810   /**
811    *  @overload
812    */
813   template<typename _Functor> const _Functor* target() const;
814
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;
821
822   typedef _Res (*_Invoker_type)(const _Any_data& _GLIBCXX_COMMA
823                                 _GLIBCXX_PARAMS);
824   _Invoker_type _M_invoker;
825 };
826
827 template<typename _Res _GLIBCXX_COMMA _GLIBCXX_TEMPLATE_PARAMS>
828   function<_Res(_GLIBCXX_TEMPLATE_ARGS)>::function(const function& __x)
829     : _Function_base()
830   {
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);
835     }
836   }
837
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()
844 {
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);
850   }
851 }
852
853 template<typename _Res _GLIBCXX_COMMA _GLIBCXX_TEMPLATE_PARAMS>
854   _Res
855   function<_Res(_GLIBCXX_TEMPLATE_ARGS)>::operator()(_GLIBCXX_PARAMS) const
856   {
857     if (_M_empty())
858       {
859 #if __EXCEPTIONS
860         throw bad_function_call();
861 #else
862         std::abort();
863 #endif
864       }
865     return _M_invoker(_M_functor _GLIBCXX_COMMA _GLIBCXX_ARGS);
866   }
867
868 template<typename _Res _GLIBCXX_COMMA _GLIBCXX_TEMPLATE_PARAMS>
869   const type_info&
870   function<_Res(_GLIBCXX_TEMPLATE_ARGS)>::target_type() const
871   {
872     if (_M_manager)
873       {
874         _Any_data __typeinfo_result;
875         _M_manager(__typeinfo_result, _M_functor, __get_type_info);
876         return *__typeinfo_result._M_access<const type_info*>();
877       }
878     else
879       {
880         return typeid(void);
881       }
882   }
883
884 template<typename _Res _GLIBCXX_COMMA _GLIBCXX_TEMPLATE_PARAMS>
885 template<typename _Functor>
886   _Functor*
887   function<_Res(_GLIBCXX_TEMPLATE_ARGS)>::target()
888   {
889     if (typeid(_Functor) == target_type() && _M_manager)
890       {
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*>();
897       }
898     else
899       {
900         return 0;
901       }
902   }
903
904 template<typename _Res _GLIBCXX_COMMA _GLIBCXX_TEMPLATE_PARAMS>
905 template<typename _Functor>
906   const _Functor*
907   function<_Res(_GLIBCXX_TEMPLATE_ARGS)>::target() const
908   {
909     if (typeid(_Functor) == target_type() && _M_manager)
910       {
911         _Any_data __ptr;
912         _M_manager(__ptr, _M_functor, __get_functor_ptr);
913         return __ptr._M_access<const _Functor*>();
914       }
915     else
916       {
917         return 0;
918       }
919   }
920
921 _GLIBCXX_END_NAMESPACE
922 }