1*f8a1b7d9SAlexander Kabaev // TR1 functional -*- C++ -*-
2*f8a1b7d9SAlexander Kabaev 
3*f8a1b7d9SAlexander Kabaev // Copyright (C) 2005, 2006 Free Software Foundation, Inc.
4*f8a1b7d9SAlexander Kabaev // Written by Douglas Gregor <doug.gregor -at- gmail.com>
5*f8a1b7d9SAlexander Kabaev //
6*f8a1b7d9SAlexander Kabaev // This file is part of the GNU ISO C++ Library.  This library is free
7*f8a1b7d9SAlexander Kabaev // software; you can redistribute it and/or modify it under the
8*f8a1b7d9SAlexander Kabaev // terms of the GNU General Public License as published by the
9*f8a1b7d9SAlexander Kabaev // Free Software Foundation; either version 2, or (at your option)
10*f8a1b7d9SAlexander Kabaev // any later version.
11*f8a1b7d9SAlexander Kabaev 
12*f8a1b7d9SAlexander Kabaev // This library is distributed in the hope that it will be useful,
13*f8a1b7d9SAlexander Kabaev // but WITHOUT ANY WARRANTY; without even the implied warranty of
14*f8a1b7d9SAlexander Kabaev // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15*f8a1b7d9SAlexander Kabaev // GNU General Public License for more details.
16*f8a1b7d9SAlexander Kabaev 
17*f8a1b7d9SAlexander Kabaev // You should have received a copy of the GNU General Public License along
18*f8a1b7d9SAlexander Kabaev // with this library; see the file COPYING.  If not, write to the Free
19*f8a1b7d9SAlexander Kabaev // Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
20*f8a1b7d9SAlexander Kabaev // USA.
21*f8a1b7d9SAlexander Kabaev 
22*f8a1b7d9SAlexander Kabaev // As a special exception, you may use this file as part of a free software
23*f8a1b7d9SAlexander Kabaev // library without restriction.  Specifically, if other files instantiate
24*f8a1b7d9SAlexander Kabaev // templates or use macros or inline functions from this file, or you compile
25*f8a1b7d9SAlexander Kabaev // this file and link it with other files to produce an executable, this
26*f8a1b7d9SAlexander Kabaev // file does not by itself cause the resulting executable to be covered by
27*f8a1b7d9SAlexander Kabaev // the GNU General Public License.  This exception does not however
28*f8a1b7d9SAlexander Kabaev // invalidate any other reasons why the executable file might be covered by
29*f8a1b7d9SAlexander Kabaev // the GNU General Public License.
30*f8a1b7d9SAlexander Kabaev 
31*f8a1b7d9SAlexander Kabaev /** @file tr1/functional_iterate.h
32*f8a1b7d9SAlexander Kabaev  *  This is an internal header file, included by other library headers.
33*f8a1b7d9SAlexander Kabaev  *  You should not attempt to use it directly.
34*f8a1b7d9SAlexander Kabaev  */
35*f8a1b7d9SAlexander Kabaev 
36*f8a1b7d9SAlexander Kabaev namespace std
37*f8a1b7d9SAlexander Kabaev {
38*f8a1b7d9SAlexander Kabaev _GLIBCXX_BEGIN_NAMESPACE(tr1)
39*f8a1b7d9SAlexander Kabaev 
40*f8a1b7d9SAlexander Kabaev template<typename _Res _GLIBCXX_COMMA _GLIBCXX_TEMPLATE_PARAMS>
41*f8a1b7d9SAlexander Kabaev   struct _Weak_result_type_impl<_Res(_GLIBCXX_TEMPLATE_ARGS)>
42*f8a1b7d9SAlexander Kabaev   {
43*f8a1b7d9SAlexander Kabaev     typedef _Res result_type;
44*f8a1b7d9SAlexander Kabaev   };
45*f8a1b7d9SAlexander Kabaev 
46*f8a1b7d9SAlexander Kabaev template<typename _Res _GLIBCXX_COMMA _GLIBCXX_TEMPLATE_PARAMS>
47*f8a1b7d9SAlexander Kabaev   struct _Weak_result_type_impl<_Res (&)(_GLIBCXX_TEMPLATE_ARGS)>
48*f8a1b7d9SAlexander Kabaev   {
49*f8a1b7d9SAlexander Kabaev     typedef _Res result_type;
50*f8a1b7d9SAlexander Kabaev   };
51*f8a1b7d9SAlexander Kabaev 
52*f8a1b7d9SAlexander Kabaev template<typename _Res _GLIBCXX_COMMA _GLIBCXX_TEMPLATE_PARAMS>
53*f8a1b7d9SAlexander Kabaev   struct _Weak_result_type_impl<_Res (*)(_GLIBCXX_TEMPLATE_ARGS)>
54*f8a1b7d9SAlexander Kabaev   {
55*f8a1b7d9SAlexander Kabaev     typedef _Res result_type;
56*f8a1b7d9SAlexander Kabaev   };
57*f8a1b7d9SAlexander Kabaev 
58*f8a1b7d9SAlexander Kabaev #if _GLIBCXX_NUM_ARGS > 0
59*f8a1b7d9SAlexander Kabaev template<typename _Res, typename _Class _GLIBCXX_COMMA_SHIFTED
60*f8a1b7d9SAlexander Kabaev          _GLIBCXX_TEMPLATE_PARAMS_SHIFTED>
61*f8a1b7d9SAlexander Kabaev   struct _Weak_result_type_impl<
62*f8a1b7d9SAlexander Kabaev            _Res (_Class::*)(_GLIBCXX_TEMPLATE_ARGS_SHIFTED)>
63*f8a1b7d9SAlexander Kabaev   {
64*f8a1b7d9SAlexander Kabaev     typedef _Res result_type;
65*f8a1b7d9SAlexander Kabaev   };
66*f8a1b7d9SAlexander Kabaev 
67*f8a1b7d9SAlexander Kabaev template<typename _Res, typename _Class _GLIBCXX_COMMA_SHIFTED
68*f8a1b7d9SAlexander Kabaev          _GLIBCXX_TEMPLATE_PARAMS_SHIFTED>
69*f8a1b7d9SAlexander Kabaev   struct _Weak_result_type_impl<
70*f8a1b7d9SAlexander Kabaev            _Res (_Class::*)(_GLIBCXX_TEMPLATE_ARGS_SHIFTED) const>
71*f8a1b7d9SAlexander Kabaev   {
72*f8a1b7d9SAlexander Kabaev     typedef _Res result_type;
73*f8a1b7d9SAlexander Kabaev   };
74*f8a1b7d9SAlexander Kabaev 
75*f8a1b7d9SAlexander Kabaev template<typename _Res, typename _Class _GLIBCXX_COMMA_SHIFTED
76*f8a1b7d9SAlexander Kabaev          _GLIBCXX_TEMPLATE_PARAMS_SHIFTED>
77*f8a1b7d9SAlexander Kabaev   struct _Weak_result_type_impl<
78*f8a1b7d9SAlexander Kabaev            _Res (_Class::*)(_GLIBCXX_TEMPLATE_ARGS_SHIFTED) volatile>
79*f8a1b7d9SAlexander Kabaev   {
80*f8a1b7d9SAlexander Kabaev     typedef _Res result_type;
81*f8a1b7d9SAlexander Kabaev   };
82*f8a1b7d9SAlexander Kabaev 
83*f8a1b7d9SAlexander Kabaev template<typename _Res, typename _Class _GLIBCXX_COMMA_SHIFTED
84*f8a1b7d9SAlexander Kabaev          _GLIBCXX_TEMPLATE_PARAMS_SHIFTED>
85*f8a1b7d9SAlexander Kabaev   struct _Weak_result_type_impl<
86*f8a1b7d9SAlexander Kabaev            _Res (_Class::*)(_GLIBCXX_TEMPLATE_ARGS_SHIFTED) const volatile>
87*f8a1b7d9SAlexander Kabaev   {
88*f8a1b7d9SAlexander Kabaev     typedef _Res result_type;
89*f8a1b7d9SAlexander Kabaev   };
90*f8a1b7d9SAlexander Kabaev #endif
91*f8a1b7d9SAlexander Kabaev 
92*f8a1b7d9SAlexander Kabaev template<typename _Functor _GLIBCXX_COMMA _GLIBCXX_TEMPLATE_PARAMS>
93*f8a1b7d9SAlexander Kabaev   class result_of<_Functor(_GLIBCXX_TEMPLATE_ARGS)>
94*f8a1b7d9SAlexander Kabaev     : public _Result_of_impl<
95*f8a1b7d9SAlexander Kabaev                _Has_result_type<_Weak_result_type<_Functor> >::value,
96*f8a1b7d9SAlexander Kabaev              _Functor(_GLIBCXX_TEMPLATE_ARGS)>
97*f8a1b7d9SAlexander Kabaev   { };
98*f8a1b7d9SAlexander Kabaev 
99*f8a1b7d9SAlexander Kabaev template<typename _Functor _GLIBCXX_COMMA _GLIBCXX_TEMPLATE_PARAMS>
100*f8a1b7d9SAlexander Kabaev   struct _Result_of_impl<true, _Functor(_GLIBCXX_TEMPLATE_ARGS)>
101*f8a1b7d9SAlexander Kabaev   {
102*f8a1b7d9SAlexander Kabaev     typedef typename _Weak_result_type<_Functor>::result_type type;
103*f8a1b7d9SAlexander Kabaev   };
104*f8a1b7d9SAlexander Kabaev 
105*f8a1b7d9SAlexander Kabaev template<typename _Functor _GLIBCXX_COMMA _GLIBCXX_TEMPLATE_PARAMS>
106*f8a1b7d9SAlexander Kabaev   struct _Result_of_impl<false, _Functor(_GLIBCXX_TEMPLATE_ARGS)>
107*f8a1b7d9SAlexander Kabaev   {
108*f8a1b7d9SAlexander Kabaev #if _GLIBCXX_NUM_ARGS > 0
109*f8a1b7d9SAlexander Kabaev     typedef typename _Functor
110*f8a1b7d9SAlexander Kabaev               ::template result<_Functor(_GLIBCXX_TEMPLATE_ARGS)>::type type;
111*f8a1b7d9SAlexander Kabaev #else
112*f8a1b7d9SAlexander Kabaev     typedef void type;
113*f8a1b7d9SAlexander Kabaev #endif
114*f8a1b7d9SAlexander Kabaev   };
115*f8a1b7d9SAlexander Kabaev 
116*f8a1b7d9SAlexander Kabaev /**
117*f8a1b7d9SAlexander Kabaev  * @if maint
118*f8a1b7d9SAlexander Kabaev  * Invoke a function object, which may be either a member pointer or a
119*f8a1b7d9SAlexander Kabaev  * function object. The first parameter will tell which.
120*f8a1b7d9SAlexander Kabaev  * @endif
121*f8a1b7d9SAlexander Kabaev  */
122*f8a1b7d9SAlexander Kabaev template<typename _Functor _GLIBCXX_COMMA _GLIBCXX_TEMPLATE_PARAMS>
123*f8a1b7d9SAlexander Kabaev   inline
124*f8a1b7d9SAlexander Kabaev   typename __gnu_cxx::__enable_if<(!is_member_pointer<_Functor>::value
125*f8a1b7d9SAlexander Kabaev 			&& !is_function<_Functor>::value
126*f8a1b7d9SAlexander Kabaev               && !is_function<typename remove_pointer<_Functor>::type>::value),
127*f8a1b7d9SAlexander Kabaev            typename result_of<_Functor(_GLIBCXX_TEMPLATE_ARGS)>::type>::__type
128*f8a1b7d9SAlexander Kabaev   __invoke(_Functor& __f _GLIBCXX_COMMA _GLIBCXX_REF_PARAMS)
129*f8a1b7d9SAlexander Kabaev   {
130*f8a1b7d9SAlexander Kabaev     return __f(_GLIBCXX_ARGS);
131*f8a1b7d9SAlexander Kabaev   }
132*f8a1b7d9SAlexander Kabaev 
133*f8a1b7d9SAlexander Kabaev #if _GLIBCXX_NUM_ARGS > 0
134*f8a1b7d9SAlexander Kabaev template<typename _Functor _GLIBCXX_COMMA _GLIBCXX_TEMPLATE_PARAMS>
135*f8a1b7d9SAlexander Kabaev   inline
136*f8a1b7d9SAlexander Kabaev   typename __gnu_cxx::__enable_if<(is_member_pointer<_Functor>::value
137*f8a1b7d9SAlexander Kabaev 			&& !is_function<_Functor>::value
138*f8a1b7d9SAlexander Kabaev               && !is_function<typename remove_pointer<_Functor>::type>::value),
139*f8a1b7d9SAlexander Kabaev              typename result_of<_Functor(_GLIBCXX_TEMPLATE_ARGS)>::type
140*f8a1b7d9SAlexander Kabaev            >::__type
141*f8a1b7d9SAlexander Kabaev   __invoke(_Functor& __f _GLIBCXX_COMMA _GLIBCXX_REF_PARAMS)
142*f8a1b7d9SAlexander Kabaev   {
143*f8a1b7d9SAlexander Kabaev     return mem_fn(__f)(_GLIBCXX_ARGS);
144*f8a1b7d9SAlexander Kabaev   }
145*f8a1b7d9SAlexander Kabaev #endif
146*f8a1b7d9SAlexander Kabaev 
147*f8a1b7d9SAlexander Kabaev // To pick up function references (that will become function pointers)
148*f8a1b7d9SAlexander Kabaev template<typename _Functor _GLIBCXX_COMMA _GLIBCXX_TEMPLATE_PARAMS>
149*f8a1b7d9SAlexander Kabaev   inline
150*f8a1b7d9SAlexander Kabaev   typename __gnu_cxx::__enable_if<(is_pointer<_Functor>::value
151*f8a1b7d9SAlexander Kabaev 	&& is_function<typename remove_pointer<_Functor>::type>::value),
152*f8a1b7d9SAlexander Kabaev              typename result_of<_Functor(_GLIBCXX_TEMPLATE_ARGS)>::type
153*f8a1b7d9SAlexander Kabaev            >::__type
154*f8a1b7d9SAlexander Kabaev   __invoke(_Functor __f _GLIBCXX_COMMA _GLIBCXX_REF_PARAMS)
155*f8a1b7d9SAlexander Kabaev   {
156*f8a1b7d9SAlexander Kabaev     return __f(_GLIBCXX_ARGS);
157*f8a1b7d9SAlexander Kabaev   }
158*f8a1b7d9SAlexander Kabaev 
159*f8a1b7d9SAlexander Kabaev /**
160*f8a1b7d9SAlexander Kabaev  * @if maint
161*f8a1b7d9SAlexander Kabaev  * Implementation of reference_wrapper::operator()
162*f8a1b7d9SAlexander Kabaev  * @endif
163*f8a1b7d9SAlexander Kabaev */
164*f8a1b7d9SAlexander Kabaev #if _GLIBCXX_NUM_ARGS > 0
165*f8a1b7d9SAlexander Kabaev template<typename _Tp>
166*f8a1b7d9SAlexander Kabaev template<_GLIBCXX_TEMPLATE_PARAMS>
167*f8a1b7d9SAlexander Kabaev   typename result_of<
168*f8a1b7d9SAlexander Kabaev    typename reference_wrapper<_Tp>::_M_func_type(_GLIBCXX_TEMPLATE_ARGS)>::type
169*f8a1b7d9SAlexander Kabaev   reference_wrapper<_Tp>::operator()(_GLIBCXX_REF_PARAMS) const
170*f8a1b7d9SAlexander Kabaev   {
171*f8a1b7d9SAlexander Kabaev     return __invoke(get(), _GLIBCXX_ARGS);
172*f8a1b7d9SAlexander Kabaev   }
173*f8a1b7d9SAlexander Kabaev #endif
174*f8a1b7d9SAlexander Kabaev 
175*f8a1b7d9SAlexander Kabaev #if _GLIBCXX_NUM_ARGS > 0
176*f8a1b7d9SAlexander Kabaev template<typename _Res, typename _Class _GLIBCXX_COMMA_SHIFTED
177*f8a1b7d9SAlexander Kabaev          _GLIBCXX_TEMPLATE_PARAMS_SHIFTED>
178*f8a1b7d9SAlexander Kabaev   class _Mem_fn<_Res (_Class::*)(_GLIBCXX_TEMPLATE_ARGS_SHIFTED)>
179*f8a1b7d9SAlexander Kabaev #if _GLIBCXX_NUM_ARGS == 1
180*f8a1b7d9SAlexander Kabaev   : public unary_function<_Class*, _Res>
181*f8a1b7d9SAlexander Kabaev #elif _GLIBCXX_NUM_ARGS == 2
182*f8a1b7d9SAlexander Kabaev     : public binary_function<_Class*, _T1, _Res>
183*f8a1b7d9SAlexander Kabaev #endif
184*f8a1b7d9SAlexander Kabaev   {
185*f8a1b7d9SAlexander Kabaev     typedef _Res (_Class::*_Functor)(_GLIBCXX_TEMPLATE_ARGS_SHIFTED);
186*f8a1b7d9SAlexander Kabaev 
187*f8a1b7d9SAlexander Kabaev     template<typename _Tp>
188*f8a1b7d9SAlexander Kabaev       _Res
189*f8a1b7d9SAlexander Kabaev       _M_call(_Tp& __object, const volatile _Class * _GLIBCXX_COMMA_SHIFTED
190*f8a1b7d9SAlexander Kabaev               _GLIBCXX_PARAMS_SHIFTED) const
191*f8a1b7d9SAlexander Kabaev       { return (__object.*__pmf)(_GLIBCXX_ARGS_SHIFTED); }
192*f8a1b7d9SAlexander Kabaev 
193*f8a1b7d9SAlexander Kabaev     template<typename _Tp>
194*f8a1b7d9SAlexander Kabaev       _Res
195*f8a1b7d9SAlexander Kabaev       _M_call(_Tp& __ptr, const volatile void * _GLIBCXX_COMMA_SHIFTED
196*f8a1b7d9SAlexander Kabaev               _GLIBCXX_PARAMS_SHIFTED) const
197*f8a1b7d9SAlexander Kabaev       {  return ((*__ptr).*__pmf)(_GLIBCXX_ARGS_SHIFTED); }
198*f8a1b7d9SAlexander Kabaev 
199*f8a1b7d9SAlexander Kabaev   public:
200*f8a1b7d9SAlexander Kabaev     typedef _Res result_type;
201*f8a1b7d9SAlexander Kabaev 
202*f8a1b7d9SAlexander Kabaev     explicit _Mem_fn(_Functor __pf) : __pmf(__pf) { }
203*f8a1b7d9SAlexander Kabaev 
204*f8a1b7d9SAlexander Kabaev     // Handle objects
205*f8a1b7d9SAlexander Kabaev     _Res
206*f8a1b7d9SAlexander Kabaev     operator()(_Class& __object _GLIBCXX_COMMA_SHIFTED
207*f8a1b7d9SAlexander Kabaev                _GLIBCXX_PARAMS_SHIFTED) const
208*f8a1b7d9SAlexander Kabaev     { return (__object.*__pmf)(_GLIBCXX_ARGS_SHIFTED); }
209*f8a1b7d9SAlexander Kabaev 
210*f8a1b7d9SAlexander Kabaev     // Handle pointers
211*f8a1b7d9SAlexander Kabaev     _Res
212*f8a1b7d9SAlexander Kabaev     operator()(_Class* __object _GLIBCXX_COMMA_SHIFTED
213*f8a1b7d9SAlexander Kabaev                _GLIBCXX_PARAMS_SHIFTED) const
214*f8a1b7d9SAlexander Kabaev     { return (__object->*__pmf)(_GLIBCXX_ARGS_SHIFTED); }
215*f8a1b7d9SAlexander Kabaev 
216*f8a1b7d9SAlexander Kabaev     // Handle smart pointers, references and pointers to derived
217*f8a1b7d9SAlexander Kabaev     template<typename _Tp>
218*f8a1b7d9SAlexander Kabaev       _Res
219*f8a1b7d9SAlexander Kabaev       operator()(_Tp& __object _GLIBCXX_COMMA_SHIFTED
220*f8a1b7d9SAlexander Kabaev                  _GLIBCXX_PARAMS_SHIFTED) const
221*f8a1b7d9SAlexander Kabaev       {
222*f8a1b7d9SAlexander Kabaev         return _M_call(__object, &__object _GLIBCXX_COMMA_SHIFTED
223*f8a1b7d9SAlexander Kabaev                        _GLIBCXX_ARGS_SHIFTED);
224*f8a1b7d9SAlexander Kabaev       }
225*f8a1b7d9SAlexander Kabaev 
226*f8a1b7d9SAlexander Kabaev   private:
227*f8a1b7d9SAlexander Kabaev     _Functor __pmf;
228*f8a1b7d9SAlexander Kabaev   };
229*f8a1b7d9SAlexander Kabaev 
230*f8a1b7d9SAlexander Kabaev template<typename _Res, typename _Class _GLIBCXX_COMMA_SHIFTED
231*f8a1b7d9SAlexander Kabaev          _GLIBCXX_TEMPLATE_PARAMS_SHIFTED>
232*f8a1b7d9SAlexander Kabaev   class _Mem_fn<_Res (_Class::*)(_GLIBCXX_TEMPLATE_ARGS_SHIFTED) const>
233*f8a1b7d9SAlexander Kabaev #if _GLIBCXX_NUM_ARGS == 1
234*f8a1b7d9SAlexander Kabaev   : public unary_function<const _Class*, _Res>
235*f8a1b7d9SAlexander Kabaev #elif _GLIBCXX_NUM_ARGS == 2
236*f8a1b7d9SAlexander Kabaev     : public binary_function<const _Class*, _T1, _Res>
237*f8a1b7d9SAlexander Kabaev #endif
238*f8a1b7d9SAlexander Kabaev   {
239*f8a1b7d9SAlexander Kabaev     typedef _Res (_Class::*_Functor)(_GLIBCXX_TEMPLATE_ARGS_SHIFTED) const;
240*f8a1b7d9SAlexander Kabaev 
241*f8a1b7d9SAlexander Kabaev      template<typename _Tp>
242*f8a1b7d9SAlexander Kabaev       _Res
243*f8a1b7d9SAlexander Kabaev       _M_call(_Tp& __object, const volatile _Class * _GLIBCXX_COMMA_SHIFTED
244*f8a1b7d9SAlexander Kabaev               _GLIBCXX_PARAMS_SHIFTED) const
245*f8a1b7d9SAlexander Kabaev       { return (__object.*__pmf)(_GLIBCXX_ARGS_SHIFTED); }
246*f8a1b7d9SAlexander Kabaev 
247*f8a1b7d9SAlexander Kabaev     template<typename _Tp>
248*f8a1b7d9SAlexander Kabaev       _Res
249*f8a1b7d9SAlexander Kabaev       _M_call(_Tp& __ptr, const volatile void * _GLIBCXX_COMMA_SHIFTED
250*f8a1b7d9SAlexander Kabaev               _GLIBCXX_PARAMS_SHIFTED) const
251*f8a1b7d9SAlexander Kabaev       {  return ((*__ptr).*__pmf)(_GLIBCXX_ARGS_SHIFTED); }
252*f8a1b7d9SAlexander Kabaev 
253*f8a1b7d9SAlexander Kabaev   public:
254*f8a1b7d9SAlexander Kabaev     typedef _Res result_type;
255*f8a1b7d9SAlexander Kabaev 
256*f8a1b7d9SAlexander Kabaev     explicit _Mem_fn(_Functor __pf) : __pmf(__pf) { }
257*f8a1b7d9SAlexander Kabaev 
258*f8a1b7d9SAlexander Kabaev     // Handle objects
259*f8a1b7d9SAlexander Kabaev     _Res
260*f8a1b7d9SAlexander Kabaev     operator()(const _Class& __object _GLIBCXX_COMMA_SHIFTED
261*f8a1b7d9SAlexander Kabaev                _GLIBCXX_PARAMS_SHIFTED) const
262*f8a1b7d9SAlexander Kabaev     { return (__object.*__pmf)(_GLIBCXX_ARGS_SHIFTED); }
263*f8a1b7d9SAlexander Kabaev 
264*f8a1b7d9SAlexander Kabaev     // Handle pointers
265*f8a1b7d9SAlexander Kabaev     _Res
266*f8a1b7d9SAlexander Kabaev     operator()(const _Class* __object _GLIBCXX_COMMA_SHIFTED
267*f8a1b7d9SAlexander Kabaev                _GLIBCXX_PARAMS_SHIFTED) const
268*f8a1b7d9SAlexander Kabaev     { return (__object->*__pmf)(_GLIBCXX_ARGS_SHIFTED); }
269*f8a1b7d9SAlexander Kabaev 
270*f8a1b7d9SAlexander Kabaev     // Handle smart pointers, references and pointers to derived
271*f8a1b7d9SAlexander Kabaev     template<typename _Tp>
272*f8a1b7d9SAlexander Kabaev       _Res
273*f8a1b7d9SAlexander Kabaev       operator()(_Tp& __object _GLIBCXX_COMMA_SHIFTED
274*f8a1b7d9SAlexander Kabaev                  _GLIBCXX_PARAMS_SHIFTED) const
275*f8a1b7d9SAlexander Kabaev       {
276*f8a1b7d9SAlexander Kabaev         return _M_call(__object, &__object _GLIBCXX_COMMA_SHIFTED
277*f8a1b7d9SAlexander Kabaev                        _GLIBCXX_ARGS_SHIFTED);
278*f8a1b7d9SAlexander Kabaev       }
279*f8a1b7d9SAlexander Kabaev 
280*f8a1b7d9SAlexander Kabaev   private:
281*f8a1b7d9SAlexander Kabaev     _Functor __pmf;
282*f8a1b7d9SAlexander Kabaev   };
283*f8a1b7d9SAlexander Kabaev 
284*f8a1b7d9SAlexander Kabaev template<typename _Res, typename _Class _GLIBCXX_COMMA_SHIFTED
285*f8a1b7d9SAlexander Kabaev          _GLIBCXX_TEMPLATE_PARAMS_SHIFTED>
286*f8a1b7d9SAlexander Kabaev   class _Mem_fn<_Res (_Class::*)(_GLIBCXX_TEMPLATE_ARGS_SHIFTED) volatile>
287*f8a1b7d9SAlexander Kabaev #if _GLIBCXX_NUM_ARGS == 1
288*f8a1b7d9SAlexander Kabaev   : public unary_function<volatile _Class*, _Res>
289*f8a1b7d9SAlexander Kabaev #elif _GLIBCXX_NUM_ARGS == 2
290*f8a1b7d9SAlexander Kabaev     : public binary_function<volatile _Class*, _T1, _Res>
291*f8a1b7d9SAlexander Kabaev #endif
292*f8a1b7d9SAlexander Kabaev   {
293*f8a1b7d9SAlexander Kabaev     typedef _Res (_Class::*_Functor)(_GLIBCXX_TEMPLATE_ARGS_SHIFTED) volatile;
294*f8a1b7d9SAlexander Kabaev 
295*f8a1b7d9SAlexander Kabaev     template<typename _Tp>
296*f8a1b7d9SAlexander Kabaev       _Res
297*f8a1b7d9SAlexander Kabaev       _M_call(_Tp& __object, const volatile _Class * _GLIBCXX_COMMA_SHIFTED
298*f8a1b7d9SAlexander Kabaev               _GLIBCXX_PARAMS_SHIFTED) const
299*f8a1b7d9SAlexander Kabaev       { return (__object.*__pmf)(_GLIBCXX_ARGS_SHIFTED); }
300*f8a1b7d9SAlexander Kabaev 
301*f8a1b7d9SAlexander Kabaev     template<typename _Tp>
302*f8a1b7d9SAlexander Kabaev       _Res
303*f8a1b7d9SAlexander Kabaev       _M_call(_Tp& __ptr, const volatile void * _GLIBCXX_COMMA_SHIFTED
304*f8a1b7d9SAlexander Kabaev               _GLIBCXX_PARAMS_SHIFTED) const
305*f8a1b7d9SAlexander Kabaev       {  return ((*__ptr).*__pmf)(_GLIBCXX_ARGS_SHIFTED); }
306*f8a1b7d9SAlexander Kabaev 
307*f8a1b7d9SAlexander Kabaev   public:
308*f8a1b7d9SAlexander Kabaev     typedef _Res result_type;
309*f8a1b7d9SAlexander Kabaev 
310*f8a1b7d9SAlexander Kabaev     explicit _Mem_fn(_Functor __pf) : __pmf(__pf) { }
311*f8a1b7d9SAlexander Kabaev 
312*f8a1b7d9SAlexander Kabaev     // Handle objects
313*f8a1b7d9SAlexander Kabaev     _Res
314*f8a1b7d9SAlexander Kabaev     operator()(volatile _Class& __object _GLIBCXX_COMMA_SHIFTED
315*f8a1b7d9SAlexander Kabaev                _GLIBCXX_PARAMS_SHIFTED) const
316*f8a1b7d9SAlexander Kabaev     { return (__object.*__pmf)(_GLIBCXX_ARGS_SHIFTED); }
317*f8a1b7d9SAlexander Kabaev 
318*f8a1b7d9SAlexander Kabaev     // Handle pointers
319*f8a1b7d9SAlexander Kabaev     _Res
320*f8a1b7d9SAlexander Kabaev     operator()(volatile _Class* __object _GLIBCXX_COMMA_SHIFTED
321*f8a1b7d9SAlexander Kabaev                _GLIBCXX_PARAMS_SHIFTED) const
322*f8a1b7d9SAlexander Kabaev     { return (__object->*__pmf)(_GLIBCXX_ARGS_SHIFTED); }
323*f8a1b7d9SAlexander Kabaev 
324*f8a1b7d9SAlexander Kabaev     // Handle smart pointers, references and pointers to derived
325*f8a1b7d9SAlexander Kabaev     template<typename _Tp>
326*f8a1b7d9SAlexander Kabaev       _Res
327*f8a1b7d9SAlexander Kabaev       operator()(_Tp& __object _GLIBCXX_COMMA_SHIFTED
328*f8a1b7d9SAlexander Kabaev                  _GLIBCXX_PARAMS_SHIFTED) const
329*f8a1b7d9SAlexander Kabaev       {
330*f8a1b7d9SAlexander Kabaev         return _M_call(__object, &__object _GLIBCXX_COMMA_SHIFTED
331*f8a1b7d9SAlexander Kabaev                        _GLIBCXX_ARGS_SHIFTED);
332*f8a1b7d9SAlexander Kabaev       }
333*f8a1b7d9SAlexander Kabaev   private:
334*f8a1b7d9SAlexander Kabaev     _Functor __pmf;
335*f8a1b7d9SAlexander Kabaev   };
336*f8a1b7d9SAlexander Kabaev 
337*f8a1b7d9SAlexander Kabaev template<typename _Res, typename _Class _GLIBCXX_COMMA_SHIFTED
338*f8a1b7d9SAlexander Kabaev          _GLIBCXX_TEMPLATE_PARAMS_SHIFTED>
339*f8a1b7d9SAlexander Kabaev   class _Mem_fn<_Res(_Class::*)(_GLIBCXX_TEMPLATE_ARGS_SHIFTED) const volatile>
340*f8a1b7d9SAlexander Kabaev #if _GLIBCXX_NUM_ARGS == 1
341*f8a1b7d9SAlexander Kabaev   : public unary_function<const volatile _Class*, _Res>
342*f8a1b7d9SAlexander Kabaev #elif _GLIBCXX_NUM_ARGS == 2
343*f8a1b7d9SAlexander Kabaev     : public binary_function<const volatile _Class*, _T1, _Res>
344*f8a1b7d9SAlexander Kabaev #endif
345*f8a1b7d9SAlexander Kabaev   {
346*f8a1b7d9SAlexander Kabaev     typedef _Res (_Class::*_Functor)(_GLIBCXX_TEMPLATE_ARGS_SHIFTED)
347*f8a1b7d9SAlexander Kabaev               const volatile;
348*f8a1b7d9SAlexander Kabaev 
349*f8a1b7d9SAlexander Kabaev     template<typename _Tp>
350*f8a1b7d9SAlexander Kabaev       _Res
351*f8a1b7d9SAlexander Kabaev       _M_call(_Tp& __object, const volatile _Class * _GLIBCXX_COMMA_SHIFTED
352*f8a1b7d9SAlexander Kabaev               _GLIBCXX_PARAMS_SHIFTED) const
353*f8a1b7d9SAlexander Kabaev       { return (__object.*__pmf)(_GLIBCXX_ARGS_SHIFTED); }
354*f8a1b7d9SAlexander Kabaev 
355*f8a1b7d9SAlexander Kabaev     template<typename _Tp>
356*f8a1b7d9SAlexander Kabaev       _Res
357*f8a1b7d9SAlexander Kabaev       _M_call(_Tp& __ptr, const volatile void * _GLIBCXX_COMMA_SHIFTED
358*f8a1b7d9SAlexander Kabaev               _GLIBCXX_PARAMS_SHIFTED) const
359*f8a1b7d9SAlexander Kabaev       {  return ((*__ptr).*__pmf)(_GLIBCXX_ARGS_SHIFTED); }
360*f8a1b7d9SAlexander Kabaev 
361*f8a1b7d9SAlexander Kabaev   public:
362*f8a1b7d9SAlexander Kabaev     typedef _Res result_type;
363*f8a1b7d9SAlexander Kabaev 
364*f8a1b7d9SAlexander Kabaev     explicit _Mem_fn(_Functor __pf) : __pmf(__pf) { }
365*f8a1b7d9SAlexander Kabaev 
366*f8a1b7d9SAlexander Kabaev     // Handle objects
367*f8a1b7d9SAlexander Kabaev     _Res
368*f8a1b7d9SAlexander Kabaev     operator()(const volatile _Class& __object _GLIBCXX_COMMA_SHIFTED
369*f8a1b7d9SAlexander Kabaev                _GLIBCXX_PARAMS_SHIFTED) const
370*f8a1b7d9SAlexander Kabaev     { return (__object.*__pmf)(_GLIBCXX_ARGS_SHIFTED); }
371*f8a1b7d9SAlexander Kabaev 
372*f8a1b7d9SAlexander Kabaev     // Handle pointers
373*f8a1b7d9SAlexander Kabaev     _Res
374*f8a1b7d9SAlexander Kabaev     operator()(const volatile _Class* __object _GLIBCXX_COMMA_SHIFTED
375*f8a1b7d9SAlexander Kabaev                _GLIBCXX_PARAMS_SHIFTED) const
376*f8a1b7d9SAlexander Kabaev     { return (__object->*__pmf)(_GLIBCXX_ARGS_SHIFTED); }
377*f8a1b7d9SAlexander Kabaev 
378*f8a1b7d9SAlexander Kabaev     // Handle smart pointers, references and pointers to derived
379*f8a1b7d9SAlexander Kabaev     template<typename _Tp>
380*f8a1b7d9SAlexander Kabaev       _Res
381*f8a1b7d9SAlexander Kabaev       operator()(_Tp& __object _GLIBCXX_COMMA_SHIFTED
382*f8a1b7d9SAlexander Kabaev                  _GLIBCXX_PARAMS_SHIFTED) const
383*f8a1b7d9SAlexander Kabaev       {
384*f8a1b7d9SAlexander Kabaev         return _M_call(__object, &__object _GLIBCXX_COMMA_SHIFTED
385*f8a1b7d9SAlexander Kabaev                        _GLIBCXX_ARGS_SHIFTED);
386*f8a1b7d9SAlexander Kabaev       }
387*f8a1b7d9SAlexander Kabaev 
388*f8a1b7d9SAlexander Kabaev   private:
389*f8a1b7d9SAlexander Kabaev     _Functor __pmf;
390*f8a1b7d9SAlexander Kabaev   };
391*f8a1b7d9SAlexander Kabaev #endif
392*f8a1b7d9SAlexander Kabaev 
393*f8a1b7d9SAlexander Kabaev #if _GLIBCXX_NUM_ARGS > 0
394*f8a1b7d9SAlexander Kabaev namespace placeholders
395*f8a1b7d9SAlexander Kabaev {
396*f8a1b7d9SAlexander Kabaev namespace
397*f8a1b7d9SAlexander Kabaev {
398*f8a1b7d9SAlexander Kabaev    _Placeholder<_GLIBCXX_NUM_ARGS> _GLIBCXX_JOIN(_,_GLIBCXX_NUM_ARGS);
399*f8a1b7d9SAlexander Kabaev } // anonymous namespace
400*f8a1b7d9SAlexander Kabaev }
401*f8a1b7d9SAlexander Kabaev #endif
402*f8a1b7d9SAlexander Kabaev 
403*f8a1b7d9SAlexander Kabaev template<typename _Functor _GLIBCXX_COMMA _GLIBCXX_TEMPLATE_PARAMS>
404*f8a1b7d9SAlexander Kabaev class _Bind<_Functor(_GLIBCXX_TEMPLATE_ARGS)>
405*f8a1b7d9SAlexander Kabaev   : public _Weak_result_type<_Functor>
406*f8a1b7d9SAlexander Kabaev {
407*f8a1b7d9SAlexander Kabaev   typedef _Bind __self_type;
408*f8a1b7d9SAlexander Kabaev 
409*f8a1b7d9SAlexander Kabaev   _Functor _M_f;
410*f8a1b7d9SAlexander Kabaev   _GLIBCXX_BIND_MEMBERS
411*f8a1b7d9SAlexander Kabaev 
412*f8a1b7d9SAlexander Kabaev  public:
413*f8a1b7d9SAlexander Kabaev #if _GLIBCXX_NUM_ARGS == 0
414*f8a1b7d9SAlexander Kabaev   explicit
415*f8a1b7d9SAlexander Kabaev #endif
416*f8a1b7d9SAlexander Kabaev   _Bind(_Functor __f _GLIBCXX_COMMA _GLIBCXX_PARAMS)
417*f8a1b7d9SAlexander Kabaev     : _M_f(__f) _GLIBCXX_COMMA _GLIBCXX_BIND_MEMBERS_INIT { }
418*f8a1b7d9SAlexander Kabaev 
419*f8a1b7d9SAlexander Kabaev #define _GLIBCXX_BIND_REPEAT_HEADER <tr1/bind_iterate.h>
420*f8a1b7d9SAlexander Kabaev #include <tr1/bind_repeat.h>
421*f8a1b7d9SAlexander Kabaev #undef _GLIBCXX_BIND_REPEAT_HEADER
422*f8a1b7d9SAlexander Kabaev };
423*f8a1b7d9SAlexander Kabaev 
424*f8a1b7d9SAlexander Kabaev template<typename _Result, typename _Functor
425*f8a1b7d9SAlexander Kabaev          _GLIBCXX_COMMA _GLIBCXX_TEMPLATE_PARAMS>
426*f8a1b7d9SAlexander Kabaev class _Bind_result<_Result, _Functor(_GLIBCXX_TEMPLATE_ARGS)>
427*f8a1b7d9SAlexander Kabaev {
428*f8a1b7d9SAlexander Kabaev   _Functor _M_f;
429*f8a1b7d9SAlexander Kabaev   _GLIBCXX_BIND_MEMBERS
430*f8a1b7d9SAlexander Kabaev 
431*f8a1b7d9SAlexander Kabaev  public:
432*f8a1b7d9SAlexander Kabaev   typedef _Result result_type;
433*f8a1b7d9SAlexander Kabaev 
434*f8a1b7d9SAlexander Kabaev #if _GLIBCXX_NUM_ARGS == 0
435*f8a1b7d9SAlexander Kabaev   explicit
436*f8a1b7d9SAlexander Kabaev #endif
437*f8a1b7d9SAlexander Kabaev   _Bind_result(_Functor __f _GLIBCXX_COMMA _GLIBCXX_PARAMS)
438*f8a1b7d9SAlexander Kabaev     : _M_f(__f) _GLIBCXX_COMMA _GLIBCXX_BIND_MEMBERS_INIT { }
439*f8a1b7d9SAlexander Kabaev 
440*f8a1b7d9SAlexander Kabaev #define _GLIBCXX_BIND_REPEAT_HEADER <tr1/bind_iterate.h>
441*f8a1b7d9SAlexander Kabaev #define _GLIBCXX_BIND_HAS_RESULT_TYPE
442*f8a1b7d9SAlexander Kabaev #include <tr1/bind_repeat.h>
443*f8a1b7d9SAlexander Kabaev #undef _GLIBCXX_BIND_HAS_RESULT_TYPE
444*f8a1b7d9SAlexander Kabaev #undef _GLIBCXX_BIND_REPEAT_HEADER
445*f8a1b7d9SAlexander Kabaev };
446*f8a1b7d9SAlexander Kabaev 
447*f8a1b7d9SAlexander Kabaev // Handle arbitrary function objects
448*f8a1b7d9SAlexander Kabaev template<typename _Functor _GLIBCXX_COMMA _GLIBCXX_TEMPLATE_PARAMS>
449*f8a1b7d9SAlexander Kabaev inline
450*f8a1b7d9SAlexander Kabaev _Bind<typename _Maybe_wrap_member_pointer<_Functor>::type
451*f8a1b7d9SAlexander Kabaev         (_GLIBCXX_TEMPLATE_ARGS)>
452*f8a1b7d9SAlexander Kabaev bind(_Functor __f _GLIBCXX_COMMA _GLIBCXX_PARAMS)
453*f8a1b7d9SAlexander Kabaev {
454*f8a1b7d9SAlexander Kabaev   typedef _Maybe_wrap_member_pointer<_Functor> __maybe_type;
455*f8a1b7d9SAlexander Kabaev   typedef typename __maybe_type::type __functor_type;
456*f8a1b7d9SAlexander Kabaev   typedef _Bind<__functor_type(_GLIBCXX_TEMPLATE_ARGS)> __result_type;
457*f8a1b7d9SAlexander Kabaev   return __result_type(__maybe_type::__do_wrap(__f)
458*f8a1b7d9SAlexander Kabaev                        _GLIBCXX_COMMA _GLIBCXX_ARGS);
459*f8a1b7d9SAlexander Kabaev }
460*f8a1b7d9SAlexander Kabaev 
461*f8a1b7d9SAlexander Kabaev template<typename _Result, typename _Functor
462*f8a1b7d9SAlexander Kabaev          _GLIBCXX_COMMA _GLIBCXX_TEMPLATE_PARAMS>
463*f8a1b7d9SAlexander Kabaev inline
464*f8a1b7d9SAlexander Kabaev _Bind_result<_Result,
465*f8a1b7d9SAlexander Kabaev              typename _Maybe_wrap_member_pointer<_Functor>::type
466*f8a1b7d9SAlexander Kabaev                (_GLIBCXX_TEMPLATE_ARGS)>
467*f8a1b7d9SAlexander Kabaev bind(_Functor __f _GLIBCXX_COMMA _GLIBCXX_PARAMS)
468*f8a1b7d9SAlexander Kabaev {
469*f8a1b7d9SAlexander Kabaev   typedef _Maybe_wrap_member_pointer<_Functor> __maybe_type;
470*f8a1b7d9SAlexander Kabaev   typedef typename __maybe_type::type __functor_type;
471*f8a1b7d9SAlexander Kabaev   typedef _Bind_result<_Result, __functor_type(_GLIBCXX_TEMPLATE_ARGS)>
472*f8a1b7d9SAlexander Kabaev     __result_type;
473*f8a1b7d9SAlexander Kabaev   return __result_type(__maybe_type::__do_wrap(__f)
474*f8a1b7d9SAlexander Kabaev                        _GLIBCXX_COMMA _GLIBCXX_ARGS);
475*f8a1b7d9SAlexander Kabaev }
476*f8a1b7d9SAlexander Kabaev 
477*f8a1b7d9SAlexander Kabaev template<typename _Res, typename _Functor _GLIBCXX_COMMA
478*f8a1b7d9SAlexander Kabaev          _GLIBCXX_TEMPLATE_PARAMS>
479*f8a1b7d9SAlexander Kabaev class _Function_handler<_Res(_GLIBCXX_TEMPLATE_ARGS), _Functor>
480*f8a1b7d9SAlexander Kabaev   : public _Function_base::_Base_manager<_Functor>
481*f8a1b7d9SAlexander Kabaev {
482*f8a1b7d9SAlexander Kabaev   typedef _Function_base::_Base_manager<_Functor> _Base;
483*f8a1b7d9SAlexander Kabaev 
484*f8a1b7d9SAlexander Kabaev  public:
485*f8a1b7d9SAlexander Kabaev   static _Res
486*f8a1b7d9SAlexander Kabaev   _M_invoke(const _Any_data& __functor _GLIBCXX_COMMA _GLIBCXX_PARAMS)
487*f8a1b7d9SAlexander Kabaev   {
488*f8a1b7d9SAlexander Kabaev     return (*_Base::_M_get_pointer(__functor))(_GLIBCXX_ARGS);
489*f8a1b7d9SAlexander Kabaev   }
490*f8a1b7d9SAlexander Kabaev };
491*f8a1b7d9SAlexander Kabaev 
492*f8a1b7d9SAlexander Kabaev template<typename _Functor _GLIBCXX_COMMA _GLIBCXX_TEMPLATE_PARAMS>
493*f8a1b7d9SAlexander Kabaev class _Function_handler<void(_GLIBCXX_TEMPLATE_ARGS), _Functor>
494*f8a1b7d9SAlexander Kabaev   : public _Function_base::_Base_manager<_Functor>
495*f8a1b7d9SAlexander Kabaev {
496*f8a1b7d9SAlexander Kabaev   typedef _Function_base::_Base_manager<_Functor> _Base;
497*f8a1b7d9SAlexander Kabaev 
498*f8a1b7d9SAlexander Kabaev  public:
499*f8a1b7d9SAlexander Kabaev   static void
500*f8a1b7d9SAlexander Kabaev   _M_invoke(const _Any_data& __functor _GLIBCXX_COMMA _GLIBCXX_PARAMS)
501*f8a1b7d9SAlexander Kabaev   {
502*f8a1b7d9SAlexander Kabaev     (*_Base::_M_get_pointer(__functor))(_GLIBCXX_ARGS);
503*f8a1b7d9SAlexander Kabaev   }
504*f8a1b7d9SAlexander Kabaev };
505*f8a1b7d9SAlexander Kabaev 
506*f8a1b7d9SAlexander Kabaev template<typename _Res, typename _Functor _GLIBCXX_COMMA
507*f8a1b7d9SAlexander Kabaev          _GLIBCXX_TEMPLATE_PARAMS>
508*f8a1b7d9SAlexander Kabaev class _Function_handler<_Res(_GLIBCXX_TEMPLATE_ARGS),
509*f8a1b7d9SAlexander Kabaev                         reference_wrapper<_Functor> >
510*f8a1b7d9SAlexander Kabaev   : public _Function_base::_Ref_manager<_Functor>
511*f8a1b7d9SAlexander Kabaev {
512*f8a1b7d9SAlexander Kabaev   typedef _Function_base::_Ref_manager<_Functor> _Base;
513*f8a1b7d9SAlexander Kabaev 
514*f8a1b7d9SAlexander Kabaev  public:
515*f8a1b7d9SAlexander Kabaev   static _Res
516*f8a1b7d9SAlexander Kabaev   _M_invoke(const _Any_data& __functor _GLIBCXX_COMMA _GLIBCXX_PARAMS)
517*f8a1b7d9SAlexander Kabaev   {
518*f8a1b7d9SAlexander Kabaev     return __callable_functor(**_Base::_M_get_pointer(__functor))
519*f8a1b7d9SAlexander Kabaev              (_GLIBCXX_ARGS);
520*f8a1b7d9SAlexander Kabaev   }
521*f8a1b7d9SAlexander Kabaev };
522*f8a1b7d9SAlexander Kabaev 
523*f8a1b7d9SAlexander Kabaev template<typename _Functor _GLIBCXX_COMMA _GLIBCXX_TEMPLATE_PARAMS>
524*f8a1b7d9SAlexander Kabaev class _Function_handler<void(_GLIBCXX_TEMPLATE_ARGS),
525*f8a1b7d9SAlexander Kabaev                         reference_wrapper<_Functor> >
526*f8a1b7d9SAlexander Kabaev   : public _Function_base::_Ref_manager<_Functor>
527*f8a1b7d9SAlexander Kabaev {
528*f8a1b7d9SAlexander Kabaev   typedef _Function_base::_Ref_manager<_Functor> _Base;
529*f8a1b7d9SAlexander Kabaev 
530*f8a1b7d9SAlexander Kabaev  public:
531*f8a1b7d9SAlexander Kabaev   static void
532*f8a1b7d9SAlexander Kabaev   _M_invoke(const _Any_data& __functor _GLIBCXX_COMMA _GLIBCXX_PARAMS)
533*f8a1b7d9SAlexander Kabaev   {
534*f8a1b7d9SAlexander Kabaev     __callable_functor(**_Base::_M_get_pointer(__functor))(_GLIBCXX_ARGS);
535*f8a1b7d9SAlexander Kabaev   }
536*f8a1b7d9SAlexander Kabaev };
537*f8a1b7d9SAlexander Kabaev 
538*f8a1b7d9SAlexander Kabaev template<typename _Class, typename _Member, typename _Res
539*f8a1b7d9SAlexander Kabaev          _GLIBCXX_COMMA _GLIBCXX_TEMPLATE_PARAMS>
540*f8a1b7d9SAlexander Kabaev class _Function_handler<_Res(_GLIBCXX_TEMPLATE_ARGS), _Member _Class::*>
541*f8a1b7d9SAlexander Kabaev   : public _Function_handler<void(_GLIBCXX_TEMPLATE_ARGS), _Member _Class::*>
542*f8a1b7d9SAlexander Kabaev {
543*f8a1b7d9SAlexander Kabaev   typedef _Function_handler<void(_GLIBCXX_TEMPLATE_ARGS), _Member _Class::*>
544*f8a1b7d9SAlexander Kabaev     _Base;
545*f8a1b7d9SAlexander Kabaev 
546*f8a1b7d9SAlexander Kabaev  public:
547*f8a1b7d9SAlexander Kabaev   static _Res
548*f8a1b7d9SAlexander Kabaev   _M_invoke(const _Any_data& __functor _GLIBCXX_COMMA _GLIBCXX_PARAMS)
549*f8a1b7d9SAlexander Kabaev   {
550*f8a1b7d9SAlexander Kabaev     return std::tr1::mem_fn(_Base::_M_get_pointer(__functor)->__value)
551*f8a1b7d9SAlexander Kabaev              (_GLIBCXX_ARGS);
552*f8a1b7d9SAlexander Kabaev   }
553*f8a1b7d9SAlexander Kabaev };
554*f8a1b7d9SAlexander Kabaev 
555*f8a1b7d9SAlexander Kabaev template<typename _Class, typename _Member
556*f8a1b7d9SAlexander Kabaev          _GLIBCXX_COMMA _GLIBCXX_TEMPLATE_PARAMS>
557*f8a1b7d9SAlexander Kabaev class _Function_handler<void(_GLIBCXX_TEMPLATE_ARGS), _Member _Class::*>
558*f8a1b7d9SAlexander Kabaev   : public _Function_base::_Base_manager<
559*f8a1b7d9SAlexander Kabaev              _Simple_type_wrapper< _Member _Class::* > >
560*f8a1b7d9SAlexander Kabaev {
561*f8a1b7d9SAlexander Kabaev   typedef _Member _Class::* _Functor;
562*f8a1b7d9SAlexander Kabaev   typedef _Simple_type_wrapper< _Functor > _Wrapper;
563*f8a1b7d9SAlexander Kabaev   typedef _Function_base::_Base_manager<_Wrapper> _Base;
564*f8a1b7d9SAlexander Kabaev 
565*f8a1b7d9SAlexander Kabaev  public:
566*f8a1b7d9SAlexander Kabaev   static bool
567*f8a1b7d9SAlexander Kabaev   _M_manager(_Any_data& __dest, const _Any_data& __source,
568*f8a1b7d9SAlexander Kabaev              _Manager_operation __op)
569*f8a1b7d9SAlexander Kabaev   {
570*f8a1b7d9SAlexander Kabaev     switch (__op) {
571*f8a1b7d9SAlexander Kabaev     case __get_type_info:
572*f8a1b7d9SAlexander Kabaev       __dest._M_access<const type_info*>() = &typeid(_Functor);
573*f8a1b7d9SAlexander Kabaev       break;
574*f8a1b7d9SAlexander Kabaev 
575*f8a1b7d9SAlexander Kabaev     case __get_functor_ptr:
576*f8a1b7d9SAlexander Kabaev       __dest._M_access<_Functor*>() =
577*f8a1b7d9SAlexander Kabaev         &_Base::_M_get_pointer(__source)->__value;
578*f8a1b7d9SAlexander Kabaev       break;
579*f8a1b7d9SAlexander Kabaev 
580*f8a1b7d9SAlexander Kabaev     default:
581*f8a1b7d9SAlexander Kabaev       _Base::_M_manager(__dest, __source, __op);
582*f8a1b7d9SAlexander Kabaev     }
583*f8a1b7d9SAlexander Kabaev     return false;
584*f8a1b7d9SAlexander Kabaev   }
585*f8a1b7d9SAlexander Kabaev 
586*f8a1b7d9SAlexander Kabaev   static void
587*f8a1b7d9SAlexander Kabaev   _M_invoke(const _Any_data& __functor _GLIBCXX_COMMA _GLIBCXX_PARAMS)
588*f8a1b7d9SAlexander Kabaev   {
589*f8a1b7d9SAlexander Kabaev     std::tr1::mem_fn(_Base::_M_get_pointer(__functor)->__value)
590*f8a1b7d9SAlexander Kabaev       (_GLIBCXX_ARGS);
591*f8a1b7d9SAlexander Kabaev   }
592*f8a1b7d9SAlexander Kabaev };
593*f8a1b7d9SAlexander Kabaev 
594*f8a1b7d9SAlexander Kabaev template<typename _Res _GLIBCXX_COMMA _GLIBCXX_TEMPLATE_PARAMS>
595*f8a1b7d9SAlexander Kabaev class function<_Res(_GLIBCXX_TEMPLATE_ARGS)>
596*f8a1b7d9SAlexander Kabaev #if _GLIBCXX_NUM_ARGS == 1
597*f8a1b7d9SAlexander Kabaev   : public unary_function<_T1, _Res>, private _Function_base
598*f8a1b7d9SAlexander Kabaev #elif _GLIBCXX_NUM_ARGS == 2
599*f8a1b7d9SAlexander Kabaev   : public binary_function<_T1, _T2, _Res>, private _Function_base
600*f8a1b7d9SAlexander Kabaev #else
601*f8a1b7d9SAlexander Kabaev   : private _Function_base
602*f8a1b7d9SAlexander Kabaev #endif
603*f8a1b7d9SAlexander Kabaev {
604*f8a1b7d9SAlexander Kabaev   /**
605*f8a1b7d9SAlexander Kabaev    *  @if maint
606*f8a1b7d9SAlexander Kabaev    *  This class is used to implement the safe_bool idiom.
607*f8a1b7d9SAlexander Kabaev    *  @endif
608*f8a1b7d9SAlexander Kabaev    */
609*f8a1b7d9SAlexander Kabaev   struct _Hidden_type
610*f8a1b7d9SAlexander Kabaev   {
611*f8a1b7d9SAlexander Kabaev     _Hidden_type* _M_bool;
612*f8a1b7d9SAlexander Kabaev   };
613*f8a1b7d9SAlexander Kabaev 
614*f8a1b7d9SAlexander Kabaev   /**
615*f8a1b7d9SAlexander Kabaev    *  @if maint
616*f8a1b7d9SAlexander Kabaev    *  This typedef is used to implement the safe_bool idiom.
617*f8a1b7d9SAlexander Kabaev    *  @endif
618*f8a1b7d9SAlexander Kabaev    */
619*f8a1b7d9SAlexander Kabaev   typedef _Hidden_type* _Hidden_type::* _Safe_bool;
620*f8a1b7d9SAlexander Kabaev 
621*f8a1b7d9SAlexander Kabaev   typedef _Res _Signature_type(_GLIBCXX_TEMPLATE_ARGS);
622*f8a1b7d9SAlexander Kabaev 
623*f8a1b7d9SAlexander Kabaev   struct _Useless {};
624*f8a1b7d9SAlexander Kabaev 
625*f8a1b7d9SAlexander Kabaev  public:
626*f8a1b7d9SAlexander Kabaev   typedef _Res result_type;
627*f8a1b7d9SAlexander Kabaev 
628*f8a1b7d9SAlexander Kabaev   // [3.7.2.1] construct/copy/destroy
629*f8a1b7d9SAlexander Kabaev 
630*f8a1b7d9SAlexander Kabaev   /**
631*f8a1b7d9SAlexander Kabaev    *  @brief Default construct creates an empty function call wrapper.
632*f8a1b7d9SAlexander Kabaev    *  @post @c !(bool)*this
633*f8a1b7d9SAlexander Kabaev    */
634*f8a1b7d9SAlexander Kabaev   function() : _Function_base() { }
635*f8a1b7d9SAlexander Kabaev 
636*f8a1b7d9SAlexander Kabaev   /**
637*f8a1b7d9SAlexander Kabaev    *  @brief Default construct creates an empty function call wrapper.
638*f8a1b7d9SAlexander Kabaev    *  @post @c !(bool)*this
639*f8a1b7d9SAlexander Kabaev    */
640*f8a1b7d9SAlexander Kabaev   function(_M_clear_type*) : _Function_base() { }
641*f8a1b7d9SAlexander Kabaev 
642*f8a1b7d9SAlexander Kabaev   /**
643*f8a1b7d9SAlexander Kabaev    *  @brief %Function copy constructor.
644*f8a1b7d9SAlexander Kabaev    *  @param x A %function object with identical call signature.
645*f8a1b7d9SAlexander Kabaev    *  @pre @c (bool)*this == (bool)x
646*f8a1b7d9SAlexander Kabaev    *
647*f8a1b7d9SAlexander Kabaev    *  The newly-created %function contains a copy of the target of @a
648*f8a1b7d9SAlexander Kabaev    *  x (if it has one).
649*f8a1b7d9SAlexander Kabaev    */
650*f8a1b7d9SAlexander Kabaev   function(const function& __x);
651*f8a1b7d9SAlexander Kabaev 
652*f8a1b7d9SAlexander Kabaev   /**
653*f8a1b7d9SAlexander Kabaev    *  @brief Builds a %function that targets a copy of the incoming
654*f8a1b7d9SAlexander Kabaev    *  function object.
655*f8a1b7d9SAlexander Kabaev    *  @param f A %function object that is callable with parameters of
656*f8a1b7d9SAlexander Kabaev    *  type @c T1, @c T2, ..., @c TN and returns a value convertible
657*f8a1b7d9SAlexander Kabaev    *  to @c Res.
658*f8a1b7d9SAlexander Kabaev    *
659*f8a1b7d9SAlexander Kabaev    *  The newly-created %function object will target a copy of @a
660*f8a1b7d9SAlexander Kabaev    *  f. If @a f is @c reference_wrapper<F>, then this function
661*f8a1b7d9SAlexander Kabaev    *  object will contain a reference to the function object @c
662*f8a1b7d9SAlexander Kabaev    *  f.get(). If @a f is a NULL function pointer or NULL
663*f8a1b7d9SAlexander Kabaev    *  pointer-to-member, the newly-created object will be empty.
664*f8a1b7d9SAlexander Kabaev    *
665*f8a1b7d9SAlexander Kabaev    *  If @a f is a non-NULL function pointer or an object of type @c
666*f8a1b7d9SAlexander Kabaev    *  reference_wrapper<F>, this function will not throw.
667*f8a1b7d9SAlexander Kabaev    */
668*f8a1b7d9SAlexander Kabaev   template<typename _Functor>
669*f8a1b7d9SAlexander Kabaev     function(_Functor __f,
670*f8a1b7d9SAlexander Kabaev              typename __gnu_cxx::__enable_if<!is_integral<_Functor>::value, _Useless>::__type = _Useless());
671*f8a1b7d9SAlexander Kabaev 
672*f8a1b7d9SAlexander Kabaev   /**
673*f8a1b7d9SAlexander Kabaev    *  @brief %Function assignment operator.
674*f8a1b7d9SAlexander Kabaev    *  @param x A %function with identical call signature.
675*f8a1b7d9SAlexander Kabaev    *  @post @c (bool)*this == (bool)x
676*f8a1b7d9SAlexander Kabaev    *  @returns @c *this
677*f8a1b7d9SAlexander Kabaev    *
678*f8a1b7d9SAlexander Kabaev    *  The target of @a x is copied to @c *this. If @a x has no
679*f8a1b7d9SAlexander Kabaev    *  target, then @c *this will be empty.
680*f8a1b7d9SAlexander Kabaev    *
681*f8a1b7d9SAlexander Kabaev    *  If @a x targets a function pointer or a reference to a function
682*f8a1b7d9SAlexander Kabaev    *  object, then this operation will not throw an exception.
683*f8a1b7d9SAlexander Kabaev    */
684*f8a1b7d9SAlexander Kabaev   function& operator=(const function& __x)
685*f8a1b7d9SAlexander Kabaev     {
686*f8a1b7d9SAlexander Kabaev       function(__x).swap(*this);
687*f8a1b7d9SAlexander Kabaev       return *this;
688*f8a1b7d9SAlexander Kabaev     }
689*f8a1b7d9SAlexander Kabaev 
690*f8a1b7d9SAlexander Kabaev   /**
691*f8a1b7d9SAlexander Kabaev    *  @brief %Function assignment to zero.
692*f8a1b7d9SAlexander Kabaev    *  @post @c !(bool)*this
693*f8a1b7d9SAlexander Kabaev    *  @returns @c *this
694*f8a1b7d9SAlexander Kabaev    *
695*f8a1b7d9SAlexander Kabaev    *  The target of @a *this is deallocated, leaving it empty.
696*f8a1b7d9SAlexander Kabaev    */
697*f8a1b7d9SAlexander Kabaev   function& operator=(_M_clear_type*)
698*f8a1b7d9SAlexander Kabaev     {
699*f8a1b7d9SAlexander Kabaev       if (_M_manager) {
700*f8a1b7d9SAlexander Kabaev         _M_manager(_M_functor, _M_functor, __destroy_functor);
701*f8a1b7d9SAlexander Kabaev         _M_manager = 0;
702*f8a1b7d9SAlexander Kabaev         _M_invoker = 0;
703*f8a1b7d9SAlexander Kabaev       }
704*f8a1b7d9SAlexander Kabaev       return *this;
705*f8a1b7d9SAlexander Kabaev     }
706*f8a1b7d9SAlexander Kabaev 
707*f8a1b7d9SAlexander Kabaev   /**
708*f8a1b7d9SAlexander Kabaev    *  @brief %Function assignment to a new target.
709*f8a1b7d9SAlexander Kabaev    *  @param f A %function object that is callable with parameters of
710*f8a1b7d9SAlexander Kabaev    *  type @c T1, @c T2, ..., @c TN and returns a value convertible
711*f8a1b7d9SAlexander Kabaev    *  to @c Res.
712*f8a1b7d9SAlexander Kabaev    *  @return @c *this
713*f8a1b7d9SAlexander Kabaev    *
714*f8a1b7d9SAlexander Kabaev    *  This  %function object wrapper will target a copy of @a
715*f8a1b7d9SAlexander Kabaev    *  f. If @a f is @c reference_wrapper<F>, then this function
716*f8a1b7d9SAlexander Kabaev    *  object will contain a reference to the function object @c
717*f8a1b7d9SAlexander Kabaev    *  f.get(). If @a f is a NULL function pointer or NULL
718*f8a1b7d9SAlexander Kabaev    *  pointer-to-member, @c this object will be empty.
719*f8a1b7d9SAlexander Kabaev    *
720*f8a1b7d9SAlexander Kabaev    *  If @a f is a non-NULL function pointer or an object of type @c
721*f8a1b7d9SAlexander Kabaev    *  reference_wrapper<F>, this function will not throw.
722*f8a1b7d9SAlexander Kabaev    */
723*f8a1b7d9SAlexander Kabaev   template<typename _Functor>
724*f8a1b7d9SAlexander Kabaev     typename __gnu_cxx::__enable_if<!is_integral<_Functor>::value, function&>::__type
725*f8a1b7d9SAlexander Kabaev     operator=(_Functor __f)
726*f8a1b7d9SAlexander Kabaev     {
727*f8a1b7d9SAlexander Kabaev       function(__f).swap(*this);
728*f8a1b7d9SAlexander Kabaev       return *this;
729*f8a1b7d9SAlexander Kabaev     }
730*f8a1b7d9SAlexander Kabaev 
731*f8a1b7d9SAlexander Kabaev   // [3.7.2.2] function modifiers
732*f8a1b7d9SAlexander Kabaev 
733*f8a1b7d9SAlexander Kabaev   /**
734*f8a1b7d9SAlexander Kabaev    *  @brief Swap the targets of two %function objects.
735*f8a1b7d9SAlexander Kabaev    *  @param f A %function with identical call signature.
736*f8a1b7d9SAlexander Kabaev    *
737*f8a1b7d9SAlexander Kabaev    *  Swap the targets of @c this function object and @a f. This
738*f8a1b7d9SAlexander Kabaev    *  function will not throw an exception.
739*f8a1b7d9SAlexander Kabaev    */
740*f8a1b7d9SAlexander Kabaev   void swap(function& __x)
741*f8a1b7d9SAlexander Kabaev   {
742*f8a1b7d9SAlexander Kabaev     _Any_data __old_functor = _M_functor;
743*f8a1b7d9SAlexander Kabaev     _M_functor = __x._M_functor;
744*f8a1b7d9SAlexander Kabaev     __x._M_functor = __old_functor;
745*f8a1b7d9SAlexander Kabaev     _Manager_type __old_manager = _M_manager;
746*f8a1b7d9SAlexander Kabaev     _M_manager = __x._M_manager;
747*f8a1b7d9SAlexander Kabaev     __x._M_manager = __old_manager;
748*f8a1b7d9SAlexander Kabaev     _Invoker_type __old_invoker = _M_invoker;
749*f8a1b7d9SAlexander Kabaev     _M_invoker = __x._M_invoker;
750*f8a1b7d9SAlexander Kabaev     __x._M_invoker = __old_invoker;
751*f8a1b7d9SAlexander Kabaev   }
752*f8a1b7d9SAlexander Kabaev 
753*f8a1b7d9SAlexander Kabaev   // [3.7.2.3] function capacity
754*f8a1b7d9SAlexander Kabaev 
755*f8a1b7d9SAlexander Kabaev   /**
756*f8a1b7d9SAlexander Kabaev    *  @brief Determine if the %function wrapper has a target.
757*f8a1b7d9SAlexander Kabaev    *
758*f8a1b7d9SAlexander Kabaev    *  @return @c true when this %function object contains a target,
759*f8a1b7d9SAlexander Kabaev    *  or @c false when it is empty.
760*f8a1b7d9SAlexander Kabaev    *
761*f8a1b7d9SAlexander Kabaev    *  This function will not throw an exception.
762*f8a1b7d9SAlexander Kabaev    */
763*f8a1b7d9SAlexander Kabaev   operator _Safe_bool() const
764*f8a1b7d9SAlexander Kabaev     {
765*f8a1b7d9SAlexander Kabaev       if (_M_empty())
766*f8a1b7d9SAlexander Kabaev         {
767*f8a1b7d9SAlexander Kabaev           return 0;
768*f8a1b7d9SAlexander Kabaev         }
769*f8a1b7d9SAlexander Kabaev       else
770*f8a1b7d9SAlexander Kabaev         {
771*f8a1b7d9SAlexander Kabaev           return &_Hidden_type::_M_bool;
772*f8a1b7d9SAlexander Kabaev         }
773*f8a1b7d9SAlexander Kabaev     }
774*f8a1b7d9SAlexander Kabaev 
775*f8a1b7d9SAlexander Kabaev   // [3.7.2.4] function invocation
776*f8a1b7d9SAlexander Kabaev 
777*f8a1b7d9SAlexander Kabaev   /**
778*f8a1b7d9SAlexander Kabaev    *  @brief Invokes the function targeted by @c *this.
779*f8a1b7d9SAlexander Kabaev    *  @returns the result of the target.
780*f8a1b7d9SAlexander Kabaev    *  @throws bad_function_call when @c !(bool)*this
781*f8a1b7d9SAlexander Kabaev    *
782*f8a1b7d9SAlexander Kabaev    *  The function call operator invokes the target function object
783*f8a1b7d9SAlexander Kabaev    *  stored by @c this.
784*f8a1b7d9SAlexander Kabaev    */
785*f8a1b7d9SAlexander Kabaev   _Res operator()(_GLIBCXX_PARAMS) const;
786*f8a1b7d9SAlexander Kabaev 
787*f8a1b7d9SAlexander Kabaev   // [3.7.2.5] function target access
788*f8a1b7d9SAlexander Kabaev   /**
789*f8a1b7d9SAlexander Kabaev    *  @brief Determine the type of the target of this function object
790*f8a1b7d9SAlexander Kabaev    *  wrapper.
791*f8a1b7d9SAlexander Kabaev    *
792*f8a1b7d9SAlexander Kabaev    *  @returns the type identifier of the target function object, or
793*f8a1b7d9SAlexander Kabaev    *  @c typeid(void) if @c !(bool)*this.
794*f8a1b7d9SAlexander Kabaev    *
795*f8a1b7d9SAlexander Kabaev    *  This function will not throw an exception.
796*f8a1b7d9SAlexander Kabaev    */
797*f8a1b7d9SAlexander Kabaev   const type_info& target_type() const;
798*f8a1b7d9SAlexander Kabaev 
799*f8a1b7d9SAlexander Kabaev   /**
800*f8a1b7d9SAlexander Kabaev    *  @brief Access the stored target function object.
801*f8a1b7d9SAlexander Kabaev    *
802*f8a1b7d9SAlexander Kabaev    *  @return Returns a pointer to the stored target function object,
803*f8a1b7d9SAlexander Kabaev    *  if @c typeid(Functor).equals(target_type()); otherwise, a NULL
804*f8a1b7d9SAlexander Kabaev    *  pointer.
805*f8a1b7d9SAlexander Kabaev    *
806*f8a1b7d9SAlexander Kabaev    * This function will not throw an exception.
807*f8a1b7d9SAlexander Kabaev    */
808*f8a1b7d9SAlexander Kabaev   template<typename _Functor>       _Functor* target();
809*f8a1b7d9SAlexander Kabaev 
810*f8a1b7d9SAlexander Kabaev   /**
811*f8a1b7d9SAlexander Kabaev    *  @overload
812*f8a1b7d9SAlexander Kabaev    */
813*f8a1b7d9SAlexander Kabaev   template<typename _Functor> const _Functor* target() const;
814*f8a1b7d9SAlexander Kabaev 
815*f8a1b7d9SAlexander Kabaev  private:
816*f8a1b7d9SAlexander Kabaev   // [3.7.2.6] undefined operators
817*f8a1b7d9SAlexander Kabaev   template<typename _Function>
818*f8a1b7d9SAlexander Kabaev     void operator==(const function<_Function>&) const;
819*f8a1b7d9SAlexander Kabaev   template<typename _Function>
820*f8a1b7d9SAlexander Kabaev     void operator!=(const function<_Function>&) const;
821*f8a1b7d9SAlexander Kabaev 
822*f8a1b7d9SAlexander Kabaev   typedef _Res (*_Invoker_type)(const _Any_data& _GLIBCXX_COMMA
823*f8a1b7d9SAlexander Kabaev                                 _GLIBCXX_PARAMS);
824*f8a1b7d9SAlexander Kabaev   _Invoker_type _M_invoker;
825*f8a1b7d9SAlexander Kabaev };
826*f8a1b7d9SAlexander Kabaev 
827*f8a1b7d9SAlexander Kabaev template<typename _Res _GLIBCXX_COMMA _GLIBCXX_TEMPLATE_PARAMS>
828*f8a1b7d9SAlexander Kabaev   function<_Res(_GLIBCXX_TEMPLATE_ARGS)>::function(const function& __x)
829*f8a1b7d9SAlexander Kabaev     : _Function_base()
830*f8a1b7d9SAlexander Kabaev   {
831*f8a1b7d9SAlexander Kabaev     if (__x) {
832*f8a1b7d9SAlexander Kabaev       _M_invoker = __x._M_invoker;
833*f8a1b7d9SAlexander Kabaev       _M_manager = __x._M_manager;
834*f8a1b7d9SAlexander Kabaev       __x._M_manager(_M_functor, __x._M_functor, __clone_functor);
835*f8a1b7d9SAlexander Kabaev     }
836*f8a1b7d9SAlexander Kabaev   }
837*f8a1b7d9SAlexander Kabaev 
838*f8a1b7d9SAlexander Kabaev template<typename _Res _GLIBCXX_COMMA _GLIBCXX_TEMPLATE_PARAMS>
839*f8a1b7d9SAlexander Kabaev template<typename _Functor>
840*f8a1b7d9SAlexander Kabaev   function<_Res(_GLIBCXX_TEMPLATE_ARGS)>
841*f8a1b7d9SAlexander Kabaev   ::function(_Functor __f,
842*f8a1b7d9SAlexander Kabaev         typename __gnu_cxx::__enable_if<!is_integral<_Functor>::value, _Useless>::__type)
843*f8a1b7d9SAlexander Kabaev     : _Function_base()
844*f8a1b7d9SAlexander Kabaev {
845*f8a1b7d9SAlexander Kabaev   typedef _Function_handler<_Signature_type, _Functor> _My_handler;
846*f8a1b7d9SAlexander Kabaev   if (_My_handler::_M_not_empty_function(__f)) {
847*f8a1b7d9SAlexander Kabaev     _M_invoker = &_My_handler::_M_invoke;
848*f8a1b7d9SAlexander Kabaev     _M_manager = &_My_handler::_M_manager;
849*f8a1b7d9SAlexander Kabaev     _My_handler::_M_init_functor(_M_functor, __f);
850*f8a1b7d9SAlexander Kabaev   }
851*f8a1b7d9SAlexander Kabaev }
852*f8a1b7d9SAlexander Kabaev 
853*f8a1b7d9SAlexander Kabaev template<typename _Res _GLIBCXX_COMMA _GLIBCXX_TEMPLATE_PARAMS>
854*f8a1b7d9SAlexander Kabaev   _Res
855*f8a1b7d9SAlexander Kabaev   function<_Res(_GLIBCXX_TEMPLATE_ARGS)>::operator()(_GLIBCXX_PARAMS) const
856*f8a1b7d9SAlexander Kabaev   {
857*f8a1b7d9SAlexander Kabaev     if (_M_empty())
858*f8a1b7d9SAlexander Kabaev       {
859*f8a1b7d9SAlexander Kabaev #if __EXCEPTIONS
860*f8a1b7d9SAlexander Kabaev         throw bad_function_call();
861*f8a1b7d9SAlexander Kabaev #else
862*f8a1b7d9SAlexander Kabaev         std::abort();
863*f8a1b7d9SAlexander Kabaev #endif
864*f8a1b7d9SAlexander Kabaev       }
865*f8a1b7d9SAlexander Kabaev     return _M_invoker(_M_functor _GLIBCXX_COMMA _GLIBCXX_ARGS);
866*f8a1b7d9SAlexander Kabaev   }
867*f8a1b7d9SAlexander Kabaev 
868*f8a1b7d9SAlexander Kabaev template<typename _Res _GLIBCXX_COMMA _GLIBCXX_TEMPLATE_PARAMS>
869*f8a1b7d9SAlexander Kabaev   const type_info&
870*f8a1b7d9SAlexander Kabaev   function<_Res(_GLIBCXX_TEMPLATE_ARGS)>::target_type() const
871*f8a1b7d9SAlexander Kabaev   {
872*f8a1b7d9SAlexander Kabaev     if (_M_manager)
873*f8a1b7d9SAlexander Kabaev       {
874*f8a1b7d9SAlexander Kabaev         _Any_data __typeinfo_result;
875*f8a1b7d9SAlexander Kabaev         _M_manager(__typeinfo_result, _M_functor, __get_type_info);
876*f8a1b7d9SAlexander Kabaev         return *__typeinfo_result._M_access<const type_info*>();
877*f8a1b7d9SAlexander Kabaev       }
878*f8a1b7d9SAlexander Kabaev     else
879*f8a1b7d9SAlexander Kabaev       {
880*f8a1b7d9SAlexander Kabaev         return typeid(void);
881*f8a1b7d9SAlexander Kabaev       }
882*f8a1b7d9SAlexander Kabaev   }
883*f8a1b7d9SAlexander Kabaev 
884*f8a1b7d9SAlexander Kabaev template<typename _Res _GLIBCXX_COMMA _GLIBCXX_TEMPLATE_PARAMS>
885*f8a1b7d9SAlexander Kabaev template<typename _Functor>
886*f8a1b7d9SAlexander Kabaev   _Functor*
887*f8a1b7d9SAlexander Kabaev   function<_Res(_GLIBCXX_TEMPLATE_ARGS)>::target()
888*f8a1b7d9SAlexander Kabaev   {
889*f8a1b7d9SAlexander Kabaev     if (typeid(_Functor) == target_type() && _M_manager)
890*f8a1b7d9SAlexander Kabaev       {
891*f8a1b7d9SAlexander Kabaev         _Any_data __ptr;
892*f8a1b7d9SAlexander Kabaev         if (_M_manager(__ptr, _M_functor, __get_functor_ptr)
893*f8a1b7d9SAlexander Kabaev             && !is_const<_Functor>::value)
894*f8a1b7d9SAlexander Kabaev           return 0;
895*f8a1b7d9SAlexander Kabaev         else
896*f8a1b7d9SAlexander Kabaev           return __ptr._M_access<_Functor*>();
897*f8a1b7d9SAlexander Kabaev       }
898*f8a1b7d9SAlexander Kabaev     else
899*f8a1b7d9SAlexander Kabaev       {
900*f8a1b7d9SAlexander Kabaev         return 0;
901*f8a1b7d9SAlexander Kabaev       }
902*f8a1b7d9SAlexander Kabaev   }
903*f8a1b7d9SAlexander Kabaev 
904*f8a1b7d9SAlexander Kabaev template<typename _Res _GLIBCXX_COMMA _GLIBCXX_TEMPLATE_PARAMS>
905*f8a1b7d9SAlexander Kabaev template<typename _Functor>
906*f8a1b7d9SAlexander Kabaev   const _Functor*
907*f8a1b7d9SAlexander Kabaev   function<_Res(_GLIBCXX_TEMPLATE_ARGS)>::target() const
908*f8a1b7d9SAlexander Kabaev   {
909*f8a1b7d9SAlexander Kabaev     if (typeid(_Functor) == target_type() && _M_manager)
910*f8a1b7d9SAlexander Kabaev       {
911*f8a1b7d9SAlexander Kabaev         _Any_data __ptr;
912*f8a1b7d9SAlexander Kabaev         _M_manager(__ptr, _M_functor, __get_functor_ptr);
913*f8a1b7d9SAlexander Kabaev         return __ptr._M_access<const _Functor*>();
914*f8a1b7d9SAlexander Kabaev       }
915*f8a1b7d9SAlexander Kabaev     else
916*f8a1b7d9SAlexander Kabaev       {
917*f8a1b7d9SAlexander Kabaev         return 0;
918*f8a1b7d9SAlexander Kabaev       }
919*f8a1b7d9SAlexander Kabaev   }
920*f8a1b7d9SAlexander Kabaev 
921*f8a1b7d9SAlexander Kabaev _GLIBCXX_END_NAMESPACE
922*f8a1b7d9SAlexander Kabaev }
923