1169691Skan// TR1 functional -*- C++ -*-
2169691Skan
3169691Skan// Copyright (C) 2005, 2006 Free Software Foundation, Inc.
4169691Skan// Written by Douglas Gregor <doug.gregor -at- gmail.com>
5169691Skan//
6169691Skan// This file is part of the GNU ISO C++ Library.  This library is free
7169691Skan// software; you can redistribute it and/or modify it under the
8169691Skan// terms of the GNU General Public License as published by the
9169691Skan// Free Software Foundation; either version 2, or (at your option)
10169691Skan// any later version.
11169691Skan
12169691Skan// This library is distributed in the hope that it will be useful,
13169691Skan// but WITHOUT ANY WARRANTY; without even the implied warranty of
14169691Skan// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15169691Skan// GNU General Public License for more details.
16169691Skan
17169691Skan// You should have received a copy of the GNU General Public License along
18169691Skan// with this library; see the file COPYING.  If not, write to the Free
19169691Skan// Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
20169691Skan// USA.
21169691Skan
22169691Skan// As a special exception, you may use this file as part of a free software
23169691Skan// library without restriction.  Specifically, if other files instantiate
24169691Skan// templates or use macros or inline functions from this file, or you compile
25169691Skan// this file and link it with other files to produce an executable, this
26169691Skan// file does not by itself cause the resulting executable to be covered by
27169691Skan// the GNU General Public License.  This exception does not however
28169691Skan// invalidate any other reasons why the executable file might be covered by
29169691Skan// the GNU General Public License.
30169691Skan
31169691Skan/** @file tr1/functional_iterate.h
32169691Skan *  This is an internal header file, included by other library headers.
33169691Skan *  You should not attempt to use it directly.
34169691Skan */
35169691Skan
36169691Skannamespace std
37169691Skan{
38169691Skan_GLIBCXX_BEGIN_NAMESPACE(tr1)
39169691Skan
40169691Skantemplate<typename _Res _GLIBCXX_COMMA _GLIBCXX_TEMPLATE_PARAMS>
41169691Skan  struct _Weak_result_type_impl<_Res(_GLIBCXX_TEMPLATE_ARGS)>
42169691Skan  {
43169691Skan    typedef _Res result_type;
44169691Skan  };
45169691Skan
46169691Skantemplate<typename _Res _GLIBCXX_COMMA _GLIBCXX_TEMPLATE_PARAMS>
47169691Skan  struct _Weak_result_type_impl<_Res (&)(_GLIBCXX_TEMPLATE_ARGS)>
48169691Skan  {
49169691Skan    typedef _Res result_type;
50169691Skan  };
51169691Skan
52169691Skantemplate<typename _Res _GLIBCXX_COMMA _GLIBCXX_TEMPLATE_PARAMS>
53169691Skan  struct _Weak_result_type_impl<_Res (*)(_GLIBCXX_TEMPLATE_ARGS)>
54169691Skan  {
55169691Skan    typedef _Res result_type;
56169691Skan  };
57169691Skan
58169691Skan#if _GLIBCXX_NUM_ARGS > 0
59169691Skantemplate<typename _Res, typename _Class _GLIBCXX_COMMA_SHIFTED
60169691Skan         _GLIBCXX_TEMPLATE_PARAMS_SHIFTED>
61169691Skan  struct _Weak_result_type_impl<
62169691Skan           _Res (_Class::*)(_GLIBCXX_TEMPLATE_ARGS_SHIFTED)>
63169691Skan  {
64169691Skan    typedef _Res result_type;
65169691Skan  };
66169691Skan
67169691Skantemplate<typename _Res, typename _Class _GLIBCXX_COMMA_SHIFTED
68169691Skan         _GLIBCXX_TEMPLATE_PARAMS_SHIFTED>
69169691Skan  struct _Weak_result_type_impl<
70169691Skan           _Res (_Class::*)(_GLIBCXX_TEMPLATE_ARGS_SHIFTED) const>
71169691Skan  {
72169691Skan    typedef _Res result_type;
73169691Skan  };
74169691Skan
75169691Skantemplate<typename _Res, typename _Class _GLIBCXX_COMMA_SHIFTED
76169691Skan         _GLIBCXX_TEMPLATE_PARAMS_SHIFTED>
77169691Skan  struct _Weak_result_type_impl<
78169691Skan           _Res (_Class::*)(_GLIBCXX_TEMPLATE_ARGS_SHIFTED) volatile>
79169691Skan  {
80169691Skan    typedef _Res result_type;
81169691Skan  };
82169691Skan
83169691Skantemplate<typename _Res, typename _Class _GLIBCXX_COMMA_SHIFTED
84169691Skan         _GLIBCXX_TEMPLATE_PARAMS_SHIFTED>
85169691Skan  struct _Weak_result_type_impl<
86169691Skan           _Res (_Class::*)(_GLIBCXX_TEMPLATE_ARGS_SHIFTED) const volatile>
87169691Skan  {
88169691Skan    typedef _Res result_type;
89169691Skan  };
90169691Skan#endif
91169691Skan
92169691Skantemplate<typename _Functor _GLIBCXX_COMMA _GLIBCXX_TEMPLATE_PARAMS>
93169691Skan  class result_of<_Functor(_GLIBCXX_TEMPLATE_ARGS)>
94169691Skan    : public _Result_of_impl<
95169691Skan               _Has_result_type<_Weak_result_type<_Functor> >::value,
96169691Skan             _Functor(_GLIBCXX_TEMPLATE_ARGS)>
97169691Skan  { };
98169691Skan
99169691Skantemplate<typename _Functor _GLIBCXX_COMMA _GLIBCXX_TEMPLATE_PARAMS>
100169691Skan  struct _Result_of_impl<true, _Functor(_GLIBCXX_TEMPLATE_ARGS)>
101169691Skan  {
102169691Skan    typedef typename _Weak_result_type<_Functor>::result_type type;
103169691Skan  };
104169691Skan
105169691Skantemplate<typename _Functor _GLIBCXX_COMMA _GLIBCXX_TEMPLATE_PARAMS>
106169691Skan  struct _Result_of_impl<false, _Functor(_GLIBCXX_TEMPLATE_ARGS)>
107169691Skan  {
108169691Skan#if _GLIBCXX_NUM_ARGS > 0
109169691Skan    typedef typename _Functor
110169691Skan              ::template result<_Functor(_GLIBCXX_TEMPLATE_ARGS)>::type type;
111169691Skan#else
112169691Skan    typedef void type;
113169691Skan#endif
114169691Skan  };
115169691Skan
116169691Skan/**
117169691Skan * @if maint
118169691Skan * Invoke a function object, which may be either a member pointer or a
119169691Skan * function object. The first parameter will tell which.
120169691Skan * @endif
121169691Skan */
122169691Skantemplate<typename _Functor _GLIBCXX_COMMA _GLIBCXX_TEMPLATE_PARAMS>
123169691Skan  inline
124169691Skan  typename __gnu_cxx::__enable_if<(!is_member_pointer<_Functor>::value
125169691Skan			&& !is_function<_Functor>::value
126169691Skan              && !is_function<typename remove_pointer<_Functor>::type>::value),
127169691Skan           typename result_of<_Functor(_GLIBCXX_TEMPLATE_ARGS)>::type>::__type
128169691Skan  __invoke(_Functor& __f _GLIBCXX_COMMA _GLIBCXX_REF_PARAMS)
129169691Skan  {
130169691Skan    return __f(_GLIBCXX_ARGS);
131169691Skan  }
132169691Skan
133169691Skan#if _GLIBCXX_NUM_ARGS > 0
134169691Skantemplate<typename _Functor _GLIBCXX_COMMA _GLIBCXX_TEMPLATE_PARAMS>
135169691Skan  inline
136169691Skan  typename __gnu_cxx::__enable_if<(is_member_pointer<_Functor>::value
137169691Skan			&& !is_function<_Functor>::value
138169691Skan              && !is_function<typename remove_pointer<_Functor>::type>::value),
139169691Skan             typename result_of<_Functor(_GLIBCXX_TEMPLATE_ARGS)>::type
140169691Skan           >::__type
141169691Skan  __invoke(_Functor& __f _GLIBCXX_COMMA _GLIBCXX_REF_PARAMS)
142169691Skan  {
143169691Skan    return mem_fn(__f)(_GLIBCXX_ARGS);
144169691Skan  }
145169691Skan#endif
146169691Skan
147169691Skan// To pick up function references (that will become function pointers)
148169691Skantemplate<typename _Functor _GLIBCXX_COMMA _GLIBCXX_TEMPLATE_PARAMS>
149169691Skan  inline
150169691Skan  typename __gnu_cxx::__enable_if<(is_pointer<_Functor>::value
151169691Skan	&& is_function<typename remove_pointer<_Functor>::type>::value),
152169691Skan             typename result_of<_Functor(_GLIBCXX_TEMPLATE_ARGS)>::type
153169691Skan           >::__type
154169691Skan  __invoke(_Functor __f _GLIBCXX_COMMA _GLIBCXX_REF_PARAMS)
155169691Skan  {
156169691Skan    return __f(_GLIBCXX_ARGS);
157169691Skan  }
158169691Skan
159169691Skan/**
160169691Skan * @if maint
161169691Skan * Implementation of reference_wrapper::operator()
162169691Skan * @endif
163169691Skan*/
164169691Skan#if _GLIBCXX_NUM_ARGS > 0
165169691Skantemplate<typename _Tp>
166169691Skantemplate<_GLIBCXX_TEMPLATE_PARAMS>
167169691Skan  typename result_of<
168169691Skan   typename reference_wrapper<_Tp>::_M_func_type(_GLIBCXX_TEMPLATE_ARGS)>::type
169169691Skan  reference_wrapper<_Tp>::operator()(_GLIBCXX_REF_PARAMS) const
170169691Skan  {
171169691Skan    return __invoke(get(), _GLIBCXX_ARGS);
172169691Skan  }
173169691Skan#endif
174169691Skan
175169691Skan#if _GLIBCXX_NUM_ARGS > 0
176169691Skantemplate<typename _Res, typename _Class _GLIBCXX_COMMA_SHIFTED
177169691Skan         _GLIBCXX_TEMPLATE_PARAMS_SHIFTED>
178169691Skan  class _Mem_fn<_Res (_Class::*)(_GLIBCXX_TEMPLATE_ARGS_SHIFTED)>
179169691Skan#if _GLIBCXX_NUM_ARGS == 1
180169691Skan  : public unary_function<_Class*, _Res>
181169691Skan#elif _GLIBCXX_NUM_ARGS == 2
182169691Skan    : public binary_function<_Class*, _T1, _Res>
183169691Skan#endif
184169691Skan  {
185169691Skan    typedef _Res (_Class::*_Functor)(_GLIBCXX_TEMPLATE_ARGS_SHIFTED);
186169691Skan
187169691Skan    template<typename _Tp>
188169691Skan      _Res
189169691Skan      _M_call(_Tp& __object, const volatile _Class * _GLIBCXX_COMMA_SHIFTED
190169691Skan              _GLIBCXX_PARAMS_SHIFTED) const
191169691Skan      { return (__object.*__pmf)(_GLIBCXX_ARGS_SHIFTED); }
192169691Skan
193169691Skan    template<typename _Tp>
194169691Skan      _Res
195169691Skan      _M_call(_Tp& __ptr, const volatile void * _GLIBCXX_COMMA_SHIFTED
196169691Skan              _GLIBCXX_PARAMS_SHIFTED) const
197169691Skan      {  return ((*__ptr).*__pmf)(_GLIBCXX_ARGS_SHIFTED); }
198169691Skan
199169691Skan  public:
200169691Skan    typedef _Res result_type;
201169691Skan
202169691Skan    explicit _Mem_fn(_Functor __pf) : __pmf(__pf) { }
203169691Skan
204169691Skan    // Handle objects
205169691Skan    _Res
206169691Skan    operator()(_Class& __object _GLIBCXX_COMMA_SHIFTED
207169691Skan               _GLIBCXX_PARAMS_SHIFTED) const
208169691Skan    { return (__object.*__pmf)(_GLIBCXX_ARGS_SHIFTED); }
209169691Skan
210169691Skan    // Handle pointers
211169691Skan    _Res
212169691Skan    operator()(_Class* __object _GLIBCXX_COMMA_SHIFTED
213169691Skan               _GLIBCXX_PARAMS_SHIFTED) const
214169691Skan    { return (__object->*__pmf)(_GLIBCXX_ARGS_SHIFTED); }
215169691Skan
216169691Skan    // Handle smart pointers, references and pointers to derived
217169691Skan    template<typename _Tp>
218169691Skan      _Res
219169691Skan      operator()(_Tp& __object _GLIBCXX_COMMA_SHIFTED
220169691Skan                 _GLIBCXX_PARAMS_SHIFTED) const
221169691Skan      {
222169691Skan        return _M_call(__object, &__object _GLIBCXX_COMMA_SHIFTED
223169691Skan                       _GLIBCXX_ARGS_SHIFTED);
224169691Skan      }
225169691Skan
226169691Skan  private:
227169691Skan    _Functor __pmf;
228169691Skan  };
229169691Skan
230169691Skantemplate<typename _Res, typename _Class _GLIBCXX_COMMA_SHIFTED
231169691Skan         _GLIBCXX_TEMPLATE_PARAMS_SHIFTED>
232169691Skan  class _Mem_fn<_Res (_Class::*)(_GLIBCXX_TEMPLATE_ARGS_SHIFTED) const>
233169691Skan#if _GLIBCXX_NUM_ARGS == 1
234169691Skan  : public unary_function<const _Class*, _Res>
235169691Skan#elif _GLIBCXX_NUM_ARGS == 2
236169691Skan    : public binary_function<const _Class*, _T1, _Res>
237169691Skan#endif
238169691Skan  {
239169691Skan    typedef _Res (_Class::*_Functor)(_GLIBCXX_TEMPLATE_ARGS_SHIFTED) const;
240169691Skan
241169691Skan     template<typename _Tp>
242169691Skan      _Res
243169691Skan      _M_call(_Tp& __object, const volatile _Class * _GLIBCXX_COMMA_SHIFTED
244169691Skan              _GLIBCXX_PARAMS_SHIFTED) const
245169691Skan      { return (__object.*__pmf)(_GLIBCXX_ARGS_SHIFTED); }
246169691Skan
247169691Skan    template<typename _Tp>
248169691Skan      _Res
249169691Skan      _M_call(_Tp& __ptr, const volatile void * _GLIBCXX_COMMA_SHIFTED
250169691Skan              _GLIBCXX_PARAMS_SHIFTED) const
251169691Skan      {  return ((*__ptr).*__pmf)(_GLIBCXX_ARGS_SHIFTED); }
252169691Skan
253169691Skan  public:
254169691Skan    typedef _Res result_type;
255169691Skan
256169691Skan    explicit _Mem_fn(_Functor __pf) : __pmf(__pf) { }
257169691Skan
258169691Skan    // Handle objects
259169691Skan    _Res
260169691Skan    operator()(const _Class& __object _GLIBCXX_COMMA_SHIFTED
261169691Skan               _GLIBCXX_PARAMS_SHIFTED) const
262169691Skan    { return (__object.*__pmf)(_GLIBCXX_ARGS_SHIFTED); }
263169691Skan
264169691Skan    // Handle pointers
265169691Skan    _Res
266169691Skan    operator()(const _Class* __object _GLIBCXX_COMMA_SHIFTED
267169691Skan               _GLIBCXX_PARAMS_SHIFTED) const
268169691Skan    { return (__object->*__pmf)(_GLIBCXX_ARGS_SHIFTED); }
269169691Skan
270169691Skan    // Handle smart pointers, references and pointers to derived
271169691Skan    template<typename _Tp>
272169691Skan      _Res
273169691Skan      operator()(_Tp& __object _GLIBCXX_COMMA_SHIFTED
274169691Skan                 _GLIBCXX_PARAMS_SHIFTED) const
275169691Skan      {
276169691Skan        return _M_call(__object, &__object _GLIBCXX_COMMA_SHIFTED
277169691Skan                       _GLIBCXX_ARGS_SHIFTED);
278169691Skan      }
279169691Skan
280169691Skan  private:
281169691Skan    _Functor __pmf;
282169691Skan  };
283169691Skan
284169691Skantemplate<typename _Res, typename _Class _GLIBCXX_COMMA_SHIFTED
285169691Skan         _GLIBCXX_TEMPLATE_PARAMS_SHIFTED>
286169691Skan  class _Mem_fn<_Res (_Class::*)(_GLIBCXX_TEMPLATE_ARGS_SHIFTED) volatile>
287169691Skan#if _GLIBCXX_NUM_ARGS == 1
288169691Skan  : public unary_function<volatile _Class*, _Res>
289169691Skan#elif _GLIBCXX_NUM_ARGS == 2
290169691Skan    : public binary_function<volatile _Class*, _T1, _Res>
291169691Skan#endif
292169691Skan  {
293169691Skan    typedef _Res (_Class::*_Functor)(_GLIBCXX_TEMPLATE_ARGS_SHIFTED) volatile;
294169691Skan
295169691Skan    template<typename _Tp>
296169691Skan      _Res
297169691Skan      _M_call(_Tp& __object, const volatile _Class * _GLIBCXX_COMMA_SHIFTED
298169691Skan              _GLIBCXX_PARAMS_SHIFTED) const
299169691Skan      { return (__object.*__pmf)(_GLIBCXX_ARGS_SHIFTED); }
300169691Skan
301169691Skan    template<typename _Tp>
302169691Skan      _Res
303169691Skan      _M_call(_Tp& __ptr, const volatile void * _GLIBCXX_COMMA_SHIFTED
304169691Skan              _GLIBCXX_PARAMS_SHIFTED) const
305169691Skan      {  return ((*__ptr).*__pmf)(_GLIBCXX_ARGS_SHIFTED); }
306169691Skan
307169691Skan  public:
308169691Skan    typedef _Res result_type;
309169691Skan
310169691Skan    explicit _Mem_fn(_Functor __pf) : __pmf(__pf) { }
311169691Skan
312169691Skan    // Handle objects
313169691Skan    _Res
314169691Skan    operator()(volatile _Class& __object _GLIBCXX_COMMA_SHIFTED
315169691Skan               _GLIBCXX_PARAMS_SHIFTED) const
316169691Skan    { return (__object.*__pmf)(_GLIBCXX_ARGS_SHIFTED); }
317169691Skan
318169691Skan    // Handle pointers
319169691Skan    _Res
320169691Skan    operator()(volatile _Class* __object _GLIBCXX_COMMA_SHIFTED
321169691Skan               _GLIBCXX_PARAMS_SHIFTED) const
322169691Skan    { return (__object->*__pmf)(_GLIBCXX_ARGS_SHIFTED); }
323169691Skan
324169691Skan    // Handle smart pointers, references and pointers to derived
325169691Skan    template<typename _Tp>
326169691Skan      _Res
327169691Skan      operator()(_Tp& __object _GLIBCXX_COMMA_SHIFTED
328169691Skan                 _GLIBCXX_PARAMS_SHIFTED) const
329169691Skan      {
330169691Skan        return _M_call(__object, &__object _GLIBCXX_COMMA_SHIFTED
331169691Skan                       _GLIBCXX_ARGS_SHIFTED);
332169691Skan      }
333169691Skan  private:
334169691Skan    _Functor __pmf;
335169691Skan  };
336169691Skan
337169691Skantemplate<typename _Res, typename _Class _GLIBCXX_COMMA_SHIFTED
338169691Skan         _GLIBCXX_TEMPLATE_PARAMS_SHIFTED>
339169691Skan  class _Mem_fn<_Res(_Class::*)(_GLIBCXX_TEMPLATE_ARGS_SHIFTED) const volatile>
340169691Skan#if _GLIBCXX_NUM_ARGS == 1
341169691Skan  : public unary_function<const volatile _Class*, _Res>
342169691Skan#elif _GLIBCXX_NUM_ARGS == 2
343169691Skan    : public binary_function<const volatile _Class*, _T1, _Res>
344169691Skan#endif
345169691Skan  {
346169691Skan    typedef _Res (_Class::*_Functor)(_GLIBCXX_TEMPLATE_ARGS_SHIFTED)
347169691Skan              const volatile;
348169691Skan
349169691Skan    template<typename _Tp>
350169691Skan      _Res
351169691Skan      _M_call(_Tp& __object, const volatile _Class * _GLIBCXX_COMMA_SHIFTED
352169691Skan              _GLIBCXX_PARAMS_SHIFTED) const
353169691Skan      { return (__object.*__pmf)(_GLIBCXX_ARGS_SHIFTED); }
354169691Skan
355169691Skan    template<typename _Tp>
356169691Skan      _Res
357169691Skan      _M_call(_Tp& __ptr, const volatile void * _GLIBCXX_COMMA_SHIFTED
358169691Skan              _GLIBCXX_PARAMS_SHIFTED) const
359169691Skan      {  return ((*__ptr).*__pmf)(_GLIBCXX_ARGS_SHIFTED); }
360169691Skan
361169691Skan  public:
362169691Skan    typedef _Res result_type;
363169691Skan
364169691Skan    explicit _Mem_fn(_Functor __pf) : __pmf(__pf) { }
365169691Skan
366169691Skan    // Handle objects
367169691Skan    _Res
368169691Skan    operator()(const volatile _Class& __object _GLIBCXX_COMMA_SHIFTED
369169691Skan               _GLIBCXX_PARAMS_SHIFTED) const
370169691Skan    { return (__object.*__pmf)(_GLIBCXX_ARGS_SHIFTED); }
371169691Skan
372169691Skan    // Handle pointers
373169691Skan    _Res
374169691Skan    operator()(const volatile _Class* __object _GLIBCXX_COMMA_SHIFTED
375169691Skan               _GLIBCXX_PARAMS_SHIFTED) const
376169691Skan    { return (__object->*__pmf)(_GLIBCXX_ARGS_SHIFTED); }
377169691Skan
378169691Skan    // Handle smart pointers, references and pointers to derived
379169691Skan    template<typename _Tp>
380169691Skan      _Res
381169691Skan      operator()(_Tp& __object _GLIBCXX_COMMA_SHIFTED
382169691Skan                 _GLIBCXX_PARAMS_SHIFTED) const
383169691Skan      {
384169691Skan        return _M_call(__object, &__object _GLIBCXX_COMMA_SHIFTED
385169691Skan                       _GLIBCXX_ARGS_SHIFTED);
386169691Skan      }
387169691Skan
388169691Skan  private:
389169691Skan    _Functor __pmf;
390169691Skan  };
391169691Skan#endif
392169691Skan
393169691Skan#if _GLIBCXX_NUM_ARGS > 0
394169691Skannamespace placeholders
395169691Skan{
396169691Skannamespace
397169691Skan{
398169691Skan   _Placeholder<_GLIBCXX_NUM_ARGS> _GLIBCXX_JOIN(_,_GLIBCXX_NUM_ARGS);
399169691Skan} // anonymous namespace
400169691Skan}
401169691Skan#endif
402169691Skan
403169691Skantemplate<typename _Functor _GLIBCXX_COMMA _GLIBCXX_TEMPLATE_PARAMS>
404169691Skanclass _Bind<_Functor(_GLIBCXX_TEMPLATE_ARGS)>
405169691Skan  : public _Weak_result_type<_Functor>
406169691Skan{
407169691Skan  typedef _Bind __self_type;
408169691Skan
409169691Skan  _Functor _M_f;
410169691Skan  _GLIBCXX_BIND_MEMBERS
411169691Skan
412169691Skan public:
413169691Skan#if _GLIBCXX_NUM_ARGS == 0
414169691Skan  explicit
415169691Skan#endif
416169691Skan  _Bind(_Functor __f _GLIBCXX_COMMA _GLIBCXX_PARAMS)
417169691Skan    : _M_f(__f) _GLIBCXX_COMMA _GLIBCXX_BIND_MEMBERS_INIT { }
418169691Skan
419169691Skan#define _GLIBCXX_BIND_REPEAT_HEADER <tr1/bind_iterate.h>
420169691Skan#include <tr1/bind_repeat.h>
421169691Skan#undef _GLIBCXX_BIND_REPEAT_HEADER
422169691Skan};
423169691Skan
424169691Skantemplate<typename _Result, typename _Functor
425169691Skan         _GLIBCXX_COMMA _GLIBCXX_TEMPLATE_PARAMS>
426169691Skanclass _Bind_result<_Result, _Functor(_GLIBCXX_TEMPLATE_ARGS)>
427169691Skan{
428169691Skan  _Functor _M_f;
429169691Skan  _GLIBCXX_BIND_MEMBERS
430169691Skan
431169691Skan public:
432169691Skan  typedef _Result result_type;
433169691Skan
434169691Skan#if _GLIBCXX_NUM_ARGS == 0
435169691Skan  explicit
436169691Skan#endif
437169691Skan  _Bind_result(_Functor __f _GLIBCXX_COMMA _GLIBCXX_PARAMS)
438169691Skan    : _M_f(__f) _GLIBCXX_COMMA _GLIBCXX_BIND_MEMBERS_INIT { }
439169691Skan
440169691Skan#define _GLIBCXX_BIND_REPEAT_HEADER <tr1/bind_iterate.h>
441169691Skan#define _GLIBCXX_BIND_HAS_RESULT_TYPE
442169691Skan#include <tr1/bind_repeat.h>
443169691Skan#undef _GLIBCXX_BIND_HAS_RESULT_TYPE
444169691Skan#undef _GLIBCXX_BIND_REPEAT_HEADER
445169691Skan};
446169691Skan
447169691Skan// Handle arbitrary function objects
448169691Skantemplate<typename _Functor _GLIBCXX_COMMA _GLIBCXX_TEMPLATE_PARAMS>
449169691Skaninline
450169691Skan_Bind<typename _Maybe_wrap_member_pointer<_Functor>::type
451169691Skan        (_GLIBCXX_TEMPLATE_ARGS)>
452169691Skanbind(_Functor __f _GLIBCXX_COMMA _GLIBCXX_PARAMS)
453169691Skan{
454169691Skan  typedef _Maybe_wrap_member_pointer<_Functor> __maybe_type;
455169691Skan  typedef typename __maybe_type::type __functor_type;
456169691Skan  typedef _Bind<__functor_type(_GLIBCXX_TEMPLATE_ARGS)> __result_type;
457169691Skan  return __result_type(__maybe_type::__do_wrap(__f)
458169691Skan                       _GLIBCXX_COMMA _GLIBCXX_ARGS);
459169691Skan}
460169691Skan
461169691Skantemplate<typename _Result, typename _Functor
462169691Skan         _GLIBCXX_COMMA _GLIBCXX_TEMPLATE_PARAMS>
463169691Skaninline
464169691Skan_Bind_result<_Result,
465169691Skan             typename _Maybe_wrap_member_pointer<_Functor>::type
466169691Skan               (_GLIBCXX_TEMPLATE_ARGS)>
467169691Skanbind(_Functor __f _GLIBCXX_COMMA _GLIBCXX_PARAMS)
468169691Skan{
469169691Skan  typedef _Maybe_wrap_member_pointer<_Functor> __maybe_type;
470169691Skan  typedef typename __maybe_type::type __functor_type;
471169691Skan  typedef _Bind_result<_Result, __functor_type(_GLIBCXX_TEMPLATE_ARGS)>
472169691Skan    __result_type;
473169691Skan  return __result_type(__maybe_type::__do_wrap(__f)
474169691Skan                       _GLIBCXX_COMMA _GLIBCXX_ARGS);
475169691Skan}
476169691Skan
477169691Skantemplate<typename _Res, typename _Functor _GLIBCXX_COMMA
478169691Skan         _GLIBCXX_TEMPLATE_PARAMS>
479169691Skanclass _Function_handler<_Res(_GLIBCXX_TEMPLATE_ARGS), _Functor>
480169691Skan  : public _Function_base::_Base_manager<_Functor>
481169691Skan{
482169691Skan  typedef _Function_base::_Base_manager<_Functor> _Base;
483169691Skan
484169691Skan public:
485169691Skan  static _Res
486169691Skan  _M_invoke(const _Any_data& __functor _GLIBCXX_COMMA _GLIBCXX_PARAMS)
487169691Skan  {
488169691Skan    return (*_Base::_M_get_pointer(__functor))(_GLIBCXX_ARGS);
489169691Skan  }
490169691Skan};
491169691Skan
492169691Skantemplate<typename _Functor _GLIBCXX_COMMA _GLIBCXX_TEMPLATE_PARAMS>
493169691Skanclass _Function_handler<void(_GLIBCXX_TEMPLATE_ARGS), _Functor>
494169691Skan  : public _Function_base::_Base_manager<_Functor>
495169691Skan{
496169691Skan  typedef _Function_base::_Base_manager<_Functor> _Base;
497169691Skan
498169691Skan public:
499169691Skan  static void
500169691Skan  _M_invoke(const _Any_data& __functor _GLIBCXX_COMMA _GLIBCXX_PARAMS)
501169691Skan  {
502169691Skan    (*_Base::_M_get_pointer(__functor))(_GLIBCXX_ARGS);
503169691Skan  }
504169691Skan};
505169691Skan
506169691Skantemplate<typename _Res, typename _Functor _GLIBCXX_COMMA
507169691Skan         _GLIBCXX_TEMPLATE_PARAMS>
508169691Skanclass _Function_handler<_Res(_GLIBCXX_TEMPLATE_ARGS),
509169691Skan                        reference_wrapper<_Functor> >
510169691Skan  : public _Function_base::_Ref_manager<_Functor>
511169691Skan{
512169691Skan  typedef _Function_base::_Ref_manager<_Functor> _Base;
513169691Skan
514169691Skan public:
515169691Skan  static _Res
516169691Skan  _M_invoke(const _Any_data& __functor _GLIBCXX_COMMA _GLIBCXX_PARAMS)
517169691Skan  {
518169691Skan    return __callable_functor(**_Base::_M_get_pointer(__functor))
519169691Skan             (_GLIBCXX_ARGS);
520169691Skan  }
521169691Skan};
522169691Skan
523169691Skantemplate<typename _Functor _GLIBCXX_COMMA _GLIBCXX_TEMPLATE_PARAMS>
524169691Skanclass _Function_handler<void(_GLIBCXX_TEMPLATE_ARGS),
525169691Skan                        reference_wrapper<_Functor> >
526169691Skan  : public _Function_base::_Ref_manager<_Functor>
527169691Skan{
528169691Skan  typedef _Function_base::_Ref_manager<_Functor> _Base;
529169691Skan
530169691Skan public:
531169691Skan  static void
532169691Skan  _M_invoke(const _Any_data& __functor _GLIBCXX_COMMA _GLIBCXX_PARAMS)
533169691Skan  {
534169691Skan    __callable_functor(**_Base::_M_get_pointer(__functor))(_GLIBCXX_ARGS);
535169691Skan  }
536169691Skan};
537169691Skan
538169691Skantemplate<typename _Class, typename _Member, typename _Res
539169691Skan         _GLIBCXX_COMMA _GLIBCXX_TEMPLATE_PARAMS>
540169691Skanclass _Function_handler<_Res(_GLIBCXX_TEMPLATE_ARGS), _Member _Class::*>
541169691Skan  : public _Function_handler<void(_GLIBCXX_TEMPLATE_ARGS), _Member _Class::*>
542169691Skan{
543169691Skan  typedef _Function_handler<void(_GLIBCXX_TEMPLATE_ARGS), _Member _Class::*>
544169691Skan    _Base;
545169691Skan
546169691Skan public:
547169691Skan  static _Res
548169691Skan  _M_invoke(const _Any_data& __functor _GLIBCXX_COMMA _GLIBCXX_PARAMS)
549169691Skan  {
550169691Skan    return std::tr1::mem_fn(_Base::_M_get_pointer(__functor)->__value)
551169691Skan             (_GLIBCXX_ARGS);
552169691Skan  }
553169691Skan};
554169691Skan
555169691Skantemplate<typename _Class, typename _Member
556169691Skan         _GLIBCXX_COMMA _GLIBCXX_TEMPLATE_PARAMS>
557169691Skanclass _Function_handler<void(_GLIBCXX_TEMPLATE_ARGS), _Member _Class::*>
558169691Skan  : public _Function_base::_Base_manager<
559169691Skan             _Simple_type_wrapper< _Member _Class::* > >
560169691Skan{
561169691Skan  typedef _Member _Class::* _Functor;
562169691Skan  typedef _Simple_type_wrapper< _Functor > _Wrapper;
563169691Skan  typedef _Function_base::_Base_manager<_Wrapper> _Base;
564169691Skan
565169691Skan public:
566169691Skan  static bool
567169691Skan  _M_manager(_Any_data& __dest, const _Any_data& __source,
568169691Skan             _Manager_operation __op)
569169691Skan  {
570169691Skan    switch (__op) {
571169691Skan    case __get_type_info:
572169691Skan      __dest._M_access<const type_info*>() = &typeid(_Functor);
573169691Skan      break;
574169691Skan
575169691Skan    case __get_functor_ptr:
576169691Skan      __dest._M_access<_Functor*>() =
577169691Skan        &_Base::_M_get_pointer(__source)->__value;
578169691Skan      break;
579169691Skan
580169691Skan    default:
581169691Skan      _Base::_M_manager(__dest, __source, __op);
582169691Skan    }
583169691Skan    return false;
584169691Skan  }
585169691Skan
586169691Skan  static void
587169691Skan  _M_invoke(const _Any_data& __functor _GLIBCXX_COMMA _GLIBCXX_PARAMS)
588169691Skan  {
589169691Skan    std::tr1::mem_fn(_Base::_M_get_pointer(__functor)->__value)
590169691Skan      (_GLIBCXX_ARGS);
591169691Skan  }
592169691Skan};
593169691Skan
594169691Skantemplate<typename _Res _GLIBCXX_COMMA _GLIBCXX_TEMPLATE_PARAMS>
595169691Skanclass function<_Res(_GLIBCXX_TEMPLATE_ARGS)>
596169691Skan#if _GLIBCXX_NUM_ARGS == 1
597169691Skan  : public unary_function<_T1, _Res>, private _Function_base
598169691Skan#elif _GLIBCXX_NUM_ARGS == 2
599169691Skan  : public binary_function<_T1, _T2, _Res>, private _Function_base
600169691Skan#else
601169691Skan  : private _Function_base
602169691Skan#endif
603169691Skan{
604169691Skan  /**
605169691Skan   *  @if maint
606169691Skan   *  This class is used to implement the safe_bool idiom.
607169691Skan   *  @endif
608169691Skan   */
609169691Skan  struct _Hidden_type
610169691Skan  {
611169691Skan    _Hidden_type* _M_bool;
612169691Skan  };
613169691Skan
614169691Skan  /**
615169691Skan   *  @if maint
616169691Skan   *  This typedef is used to implement the safe_bool idiom.
617169691Skan   *  @endif
618169691Skan   */
619169691Skan  typedef _Hidden_type* _Hidden_type::* _Safe_bool;
620169691Skan
621169691Skan  typedef _Res _Signature_type(_GLIBCXX_TEMPLATE_ARGS);
622169691Skan
623169691Skan  struct _Useless {};
624169691Skan
625169691Skan public:
626169691Skan  typedef _Res result_type;
627169691Skan
628169691Skan  // [3.7.2.1] construct/copy/destroy
629169691Skan
630169691Skan  /**
631169691Skan   *  @brief Default construct creates an empty function call wrapper.
632169691Skan   *  @post @c !(bool)*this
633169691Skan   */
634169691Skan  function() : _Function_base() { }
635169691Skan
636169691Skan  /**
637169691Skan   *  @brief Default construct creates an empty function call wrapper.
638169691Skan   *  @post @c !(bool)*this
639169691Skan   */
640169691Skan  function(_M_clear_type*) : _Function_base() { }
641169691Skan
642169691Skan  /**
643169691Skan   *  @brief %Function copy constructor.
644169691Skan   *  @param x A %function object with identical call signature.
645169691Skan   *  @pre @c (bool)*this == (bool)x
646169691Skan   *
647169691Skan   *  The newly-created %function contains a copy of the target of @a
648169691Skan   *  x (if it has one).
649169691Skan   */
650169691Skan  function(const function& __x);
651169691Skan
652169691Skan  /**
653169691Skan   *  @brief Builds a %function that targets a copy of the incoming
654169691Skan   *  function object.
655169691Skan   *  @param f A %function object that is callable with parameters of
656169691Skan   *  type @c T1, @c T2, ..., @c TN and returns a value convertible
657169691Skan   *  to @c Res.
658169691Skan   *
659169691Skan   *  The newly-created %function object will target a copy of @a
660169691Skan   *  f. If @a f is @c reference_wrapper<F>, then this function
661169691Skan   *  object will contain a reference to the function object @c
662169691Skan   *  f.get(). If @a f is a NULL function pointer or NULL
663169691Skan   *  pointer-to-member, the newly-created object will be empty.
664169691Skan   *
665169691Skan   *  If @a f is a non-NULL function pointer or an object of type @c
666169691Skan   *  reference_wrapper<F>, this function will not throw.
667169691Skan   */
668169691Skan  template<typename _Functor>
669169691Skan    function(_Functor __f,
670169691Skan             typename __gnu_cxx::__enable_if<!is_integral<_Functor>::value, _Useless>::__type = _Useless());
671169691Skan
672169691Skan  /**
673169691Skan   *  @brief %Function assignment operator.
674169691Skan   *  @param x A %function with identical call signature.
675169691Skan   *  @post @c (bool)*this == (bool)x
676169691Skan   *  @returns @c *this
677169691Skan   *
678169691Skan   *  The target of @a x is copied to @c *this. If @a x has no
679169691Skan   *  target, then @c *this will be empty.
680169691Skan   *
681169691Skan   *  If @a x targets a function pointer or a reference to a function
682169691Skan   *  object, then this operation will not throw an exception.
683169691Skan   */
684169691Skan  function& operator=(const function& __x)
685169691Skan    {
686169691Skan      function(__x).swap(*this);
687169691Skan      return *this;
688169691Skan    }
689169691Skan
690169691Skan  /**
691169691Skan   *  @brief %Function assignment to zero.
692169691Skan   *  @post @c !(bool)*this
693169691Skan   *  @returns @c *this
694169691Skan   *
695169691Skan   *  The target of @a *this is deallocated, leaving it empty.
696169691Skan   */
697169691Skan  function& operator=(_M_clear_type*)
698169691Skan    {
699169691Skan      if (_M_manager) {
700169691Skan        _M_manager(_M_functor, _M_functor, __destroy_functor);
701169691Skan        _M_manager = 0;
702169691Skan        _M_invoker = 0;
703169691Skan      }
704169691Skan      return *this;
705169691Skan    }
706169691Skan
707169691Skan  /**
708169691Skan   *  @brief %Function assignment to a new target.
709169691Skan   *  @param f A %function object that is callable with parameters of
710169691Skan   *  type @c T1, @c T2, ..., @c TN and returns a value convertible
711169691Skan   *  to @c Res.
712169691Skan   *  @return @c *this
713169691Skan   *
714169691Skan   *  This  %function object wrapper will target a copy of @a
715169691Skan   *  f. If @a f is @c reference_wrapper<F>, then this function
716169691Skan   *  object will contain a reference to the function object @c
717169691Skan   *  f.get(). If @a f is a NULL function pointer or NULL
718169691Skan   *  pointer-to-member, @c this object will be empty.
719169691Skan   *
720169691Skan   *  If @a f is a non-NULL function pointer or an object of type @c
721169691Skan   *  reference_wrapper<F>, this function will not throw.
722169691Skan   */
723169691Skan  template<typename _Functor>
724169691Skan    typename __gnu_cxx::__enable_if<!is_integral<_Functor>::value, function&>::__type
725169691Skan    operator=(_Functor __f)
726169691Skan    {
727169691Skan      function(__f).swap(*this);
728169691Skan      return *this;
729169691Skan    }
730169691Skan
731169691Skan  // [3.7.2.2] function modifiers
732169691Skan
733169691Skan  /**
734169691Skan   *  @brief Swap the targets of two %function objects.
735169691Skan   *  @param f A %function with identical call signature.
736169691Skan   *
737169691Skan   *  Swap the targets of @c this function object and @a f. This
738169691Skan   *  function will not throw an exception.
739169691Skan   */
740169691Skan  void swap(function& __x)
741169691Skan  {
742169691Skan    _Any_data __old_functor = _M_functor;
743169691Skan    _M_functor = __x._M_functor;
744169691Skan    __x._M_functor = __old_functor;
745169691Skan    _Manager_type __old_manager = _M_manager;
746169691Skan    _M_manager = __x._M_manager;
747169691Skan    __x._M_manager = __old_manager;
748169691Skan    _Invoker_type __old_invoker = _M_invoker;
749169691Skan    _M_invoker = __x._M_invoker;
750169691Skan    __x._M_invoker = __old_invoker;
751169691Skan  }
752169691Skan
753169691Skan  // [3.7.2.3] function capacity
754169691Skan
755169691Skan  /**
756169691Skan   *  @brief Determine if the %function wrapper has a target.
757169691Skan   *
758169691Skan   *  @return @c true when this %function object contains a target,
759169691Skan   *  or @c false when it is empty.
760169691Skan   *
761169691Skan   *  This function will not throw an exception.
762169691Skan   */
763169691Skan  operator _Safe_bool() const
764169691Skan    {
765169691Skan      if (_M_empty())
766169691Skan        {
767169691Skan          return 0;
768169691Skan        }
769169691Skan      else
770169691Skan        {
771169691Skan          return &_Hidden_type::_M_bool;
772169691Skan        }
773169691Skan    }
774169691Skan
775169691Skan  // [3.7.2.4] function invocation
776169691Skan
777169691Skan  /**
778169691Skan   *  @brief Invokes the function targeted by @c *this.
779169691Skan   *  @returns the result of the target.
780169691Skan   *  @throws bad_function_call when @c !(bool)*this
781169691Skan   *
782169691Skan   *  The function call operator invokes the target function object
783169691Skan   *  stored by @c this.
784169691Skan   */
785169691Skan  _Res operator()(_GLIBCXX_PARAMS) const;
786169691Skan
787169691Skan  // [3.7.2.5] function target access
788169691Skan  /**
789169691Skan   *  @brief Determine the type of the target of this function object
790169691Skan   *  wrapper.
791169691Skan   *
792169691Skan   *  @returns the type identifier of the target function object, or
793169691Skan   *  @c typeid(void) if @c !(bool)*this.
794169691Skan   *
795169691Skan   *  This function will not throw an exception.
796169691Skan   */
797169691Skan  const type_info& target_type() const;
798169691Skan
799169691Skan  /**
800169691Skan   *  @brief Access the stored target function object.
801169691Skan   *
802169691Skan   *  @return Returns a pointer to the stored target function object,
803169691Skan   *  if @c typeid(Functor).equals(target_type()); otherwise, a NULL
804169691Skan   *  pointer.
805169691Skan   *
806169691Skan   * This function will not throw an exception.
807169691Skan   */
808169691Skan  template<typename _Functor>       _Functor* target();
809169691Skan
810169691Skan  /**
811169691Skan   *  @overload
812169691Skan   */
813169691Skan  template<typename _Functor> const _Functor* target() const;
814169691Skan
815169691Skan private:
816169691Skan  // [3.7.2.6] undefined operators
817169691Skan  template<typename _Function>
818169691Skan    void operator==(const function<_Function>&) const;
819169691Skan  template<typename _Function>
820169691Skan    void operator!=(const function<_Function>&) const;
821169691Skan
822169691Skan  typedef _Res (*_Invoker_type)(const _Any_data& _GLIBCXX_COMMA
823169691Skan                                _GLIBCXX_PARAMS);
824169691Skan  _Invoker_type _M_invoker;
825169691Skan};
826169691Skan
827169691Skantemplate<typename _Res _GLIBCXX_COMMA _GLIBCXX_TEMPLATE_PARAMS>
828169691Skan  function<_Res(_GLIBCXX_TEMPLATE_ARGS)>::function(const function& __x)
829169691Skan    : _Function_base()
830169691Skan  {
831169691Skan    if (__x) {
832169691Skan      _M_invoker = __x._M_invoker;
833169691Skan      _M_manager = __x._M_manager;
834169691Skan      __x._M_manager(_M_functor, __x._M_functor, __clone_functor);
835169691Skan    }
836169691Skan  }
837169691Skan
838169691Skantemplate<typename _Res _GLIBCXX_COMMA _GLIBCXX_TEMPLATE_PARAMS>
839169691Skantemplate<typename _Functor>
840169691Skan  function<_Res(_GLIBCXX_TEMPLATE_ARGS)>
841169691Skan  ::function(_Functor __f,
842169691Skan        typename __gnu_cxx::__enable_if<!is_integral<_Functor>::value, _Useless>::__type)
843169691Skan    : _Function_base()
844169691Skan{
845169691Skan  typedef _Function_handler<_Signature_type, _Functor> _My_handler;
846169691Skan  if (_My_handler::_M_not_empty_function(__f)) {
847169691Skan    _M_invoker = &_My_handler::_M_invoke;
848169691Skan    _M_manager = &_My_handler::_M_manager;
849169691Skan    _My_handler::_M_init_functor(_M_functor, __f);
850169691Skan  }
851169691Skan}
852169691Skan
853169691Skantemplate<typename _Res _GLIBCXX_COMMA _GLIBCXX_TEMPLATE_PARAMS>
854169691Skan  _Res
855169691Skan  function<_Res(_GLIBCXX_TEMPLATE_ARGS)>::operator()(_GLIBCXX_PARAMS) const
856169691Skan  {
857169691Skan    if (_M_empty())
858169691Skan      {
859169691Skan#if __EXCEPTIONS
860169691Skan        throw bad_function_call();
861169691Skan#else
862169691Skan        std::abort();
863169691Skan#endif
864169691Skan      }
865169691Skan    return _M_invoker(_M_functor _GLIBCXX_COMMA _GLIBCXX_ARGS);
866169691Skan  }
867169691Skan
868169691Skantemplate<typename _Res _GLIBCXX_COMMA _GLIBCXX_TEMPLATE_PARAMS>
869169691Skan  const type_info&
870169691Skan  function<_Res(_GLIBCXX_TEMPLATE_ARGS)>::target_type() const
871169691Skan  {
872169691Skan    if (_M_manager)
873169691Skan      {
874169691Skan        _Any_data __typeinfo_result;
875169691Skan        _M_manager(__typeinfo_result, _M_functor, __get_type_info);
876169691Skan        return *__typeinfo_result._M_access<const type_info*>();
877169691Skan      }
878169691Skan    else
879169691Skan      {
880169691Skan        return typeid(void);
881169691Skan      }
882169691Skan  }
883169691Skan
884169691Skantemplate<typename _Res _GLIBCXX_COMMA _GLIBCXX_TEMPLATE_PARAMS>
885169691Skantemplate<typename _Functor>
886169691Skan  _Functor*
887169691Skan  function<_Res(_GLIBCXX_TEMPLATE_ARGS)>::target()
888169691Skan  {
889169691Skan    if (typeid(_Functor) == target_type() && _M_manager)
890169691Skan      {
891169691Skan        _Any_data __ptr;
892169691Skan        if (_M_manager(__ptr, _M_functor, __get_functor_ptr)
893169691Skan            && !is_const<_Functor>::value)
894169691Skan          return 0;
895169691Skan        else
896169691Skan          return __ptr._M_access<_Functor*>();
897169691Skan      }
898169691Skan    else
899169691Skan      {
900169691Skan        return 0;
901169691Skan      }
902169691Skan  }
903169691Skan
904169691Skantemplate<typename _Res _GLIBCXX_COMMA _GLIBCXX_TEMPLATE_PARAMS>
905169691Skantemplate<typename _Functor>
906169691Skan  const _Functor*
907169691Skan  function<_Res(_GLIBCXX_TEMPLATE_ARGS)>::target() const
908169691Skan  {
909169691Skan    if (typeid(_Functor) == target_type() && _M_manager)
910169691Skan      {
911169691Skan        _Any_data __ptr;
912169691Skan        _M_manager(__ptr, _M_functor, __get_functor_ptr);
913169691Skan        return __ptr._M_access<const _Functor*>();
914169691Skan      }
915169691Skan    else
916169691Skan      {
917169691Skan        return 0;
918169691Skan      }
919169691Skan  }
920169691Skan
921169691Skan_GLIBCXX_END_NAMESPACE
922169691Skan}
923