functional_iterate.h

Go to the documentation of this file.
00001 // TR1 functional -*- C++ -*-
00002 
00003 // Copyright (C) 2005, 2006 Free Software Foundation, Inc.
00004 // Written by Douglas Gregor <doug.gregor -at- gmail.com>
00005 //
00006 // This file is part of the GNU ISO C++ Library.  This library is free
00007 // software; you can redistribute it and/or modify it under the
00008 // terms of the GNU General Public License as published by the
00009 // Free Software Foundation; either version 2, or (at your option)
00010 // any later version.
00011 
00012 // This library is distributed in the hope that it will be useful,
00013 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00014 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00015 // GNU General Public License for more details.
00016 
00017 // You should have received a copy of the GNU General Public License along
00018 // with this library; see the file COPYING.  If not, write to the Free
00019 // Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
00020 // USA.
00021 
00022 // As a special exception, you may use this file as part of a free software
00023 // library without restriction.  Specifically, if other files instantiate
00024 // templates or use macros or inline functions from this file, or you compile
00025 // this file and link it with other files to produce an executable, this
00026 // file does not by itself cause the resulting executable to be covered by
00027 // the GNU General Public License.  This exception does not however
00028 // invalidate any other reasons why the executable file might be covered by
00029 // the GNU General Public License.
00030 
00036 template<typename _Res _GLIBCXX_COMMA _GLIBCXX_TEMPLATE_PARAMS>
00037   struct _Weak_result_type_impl<_Res(_GLIBCXX_TEMPLATE_ARGS)>
00038   {
00039     typedef _Res result_type;
00040   };
00041 
00042 template<typename _Res _GLIBCXX_COMMA _GLIBCXX_TEMPLATE_PARAMS>
00043   struct _Weak_result_type_impl<_Res (&)(_GLIBCXX_TEMPLATE_ARGS)>
00044   {
00045     typedef _Res result_type;
00046   };
00047 
00048 template<typename _Res _GLIBCXX_COMMA _GLIBCXX_TEMPLATE_PARAMS>
00049   struct _Weak_result_type_impl<_Res (*)(_GLIBCXX_TEMPLATE_ARGS)>
00050   {
00051     typedef _Res result_type;
00052   };
00053 
00054 #if _GLIBCXX_NUM_ARGS > 0
00055 template<typename _Res, typename _Class _GLIBCXX_COMMA_SHIFTED
00056          _GLIBCXX_TEMPLATE_PARAMS_SHIFTED>
00057   struct _Weak_result_type_impl<
00058            _Res (_Class::*)(_GLIBCXX_TEMPLATE_ARGS_SHIFTED)>
00059   {
00060     typedef _Res result_type;
00061   };
00062 
00063 template<typename _Res, typename _Class _GLIBCXX_COMMA_SHIFTED
00064          _GLIBCXX_TEMPLATE_PARAMS_SHIFTED>
00065   struct _Weak_result_type_impl<
00066            _Res (_Class::*)(_GLIBCXX_TEMPLATE_ARGS_SHIFTED) const>
00067   {
00068     typedef _Res result_type;
00069   };
00070 
00071 template<typename _Res, typename _Class _GLIBCXX_COMMA_SHIFTED
00072          _GLIBCXX_TEMPLATE_PARAMS_SHIFTED>
00073   struct _Weak_result_type_impl<
00074            _Res (_Class::*)(_GLIBCXX_TEMPLATE_ARGS_SHIFTED) volatile>
00075   {
00076     typedef _Res result_type;
00077   };
00078 
00079 template<typename _Res, typename _Class _GLIBCXX_COMMA_SHIFTED
00080          _GLIBCXX_TEMPLATE_PARAMS_SHIFTED>
00081   struct _Weak_result_type_impl<
00082            _Res (_Class::*)(_GLIBCXX_TEMPLATE_ARGS_SHIFTED) const volatile>
00083   {
00084     typedef _Res result_type;
00085   };
00086 #endif
00087 
00088 template<typename _Functor _GLIBCXX_COMMA _GLIBCXX_TEMPLATE_PARAMS>
00089   class result_of<_Functor(_GLIBCXX_TEMPLATE_ARGS)>
00090     : public _Result_of_impl<
00091                _Has_result_type<_Weak_result_type<_Functor> >::value,
00092              _Functor(_GLIBCXX_TEMPLATE_ARGS)>
00093   { };
00094 
00095 template<typename _Functor _GLIBCXX_COMMA _GLIBCXX_TEMPLATE_PARAMS>
00096   struct _Result_of_impl<true, _Functor(_GLIBCXX_TEMPLATE_ARGS)>
00097   {
00098     typedef typename _Weak_result_type<_Functor>::result_type type;
00099   };
00100 
00101 template<typename _Functor _GLIBCXX_COMMA _GLIBCXX_TEMPLATE_PARAMS>
00102   struct _Result_of_impl<false, _Functor(_GLIBCXX_TEMPLATE_ARGS)>
00103   {
00104 #if _GLIBCXX_NUM_ARGS > 0
00105     typedef typename _Functor
00106               ::template result<_Functor(_GLIBCXX_TEMPLATE_ARGS)>::type type;
00107 #else
00108     typedef void type;
00109 #endif
00110   };
00111 
00118 template<typename _Functor _GLIBCXX_COMMA _GLIBCXX_TEMPLATE_PARAMS>
00119   inline
00120   typename __enable_if<
00121              typename result_of<_Functor(_GLIBCXX_TEMPLATE_ARGS)>::type,
00122              (!is_member_pointer<_Functor>::value
00123               && !is_function<_Functor>::value
00124               && !is_function<typename remove_pointer<_Functor>::type>::value)
00125            >::__type
00126   __invoke(_Functor& __f _GLIBCXX_COMMA _GLIBCXX_REF_PARAMS)
00127   {
00128     return __f(_GLIBCXX_ARGS);
00129   }
00130 
00131 #if _GLIBCXX_NUM_ARGS > 0
00132 template<typename _Functor _GLIBCXX_COMMA _GLIBCXX_TEMPLATE_PARAMS>
00133   inline
00134   typename __enable_if<
00135              typename result_of<_Functor(_GLIBCXX_TEMPLATE_ARGS)>::type,
00136              (is_member_pointer<_Functor>::value
00137               && !is_function<_Functor>::value
00138               && !is_function<typename remove_pointer<_Functor>::type>::value)
00139            >::__type
00140   __invoke(_Functor& __f _GLIBCXX_COMMA _GLIBCXX_REF_PARAMS)
00141   {
00142     return mem_fn(__f)(_GLIBCXX_ARGS);
00143   }
00144 #endif
00145 
00146 // To pick up function references (that will become function pointers)
00147 template<typename _Functor _GLIBCXX_COMMA _GLIBCXX_TEMPLATE_PARAMS>
00148   inline
00149   typename __enable_if<
00150              typename result_of<_Functor(_GLIBCXX_TEMPLATE_ARGS)>::type,
00151              (is_pointer<_Functor>::value
00152               && is_function<typename remove_pointer<_Functor>::type>::value)
00153            >::__type
00154   __invoke(_Functor __f _GLIBCXX_COMMA _GLIBCXX_REF_PARAMS)
00155   {
00156     return __f(_GLIBCXX_ARGS);
00157   }
00158 
00164 #if _GLIBCXX_NUM_ARGS > 0
00165 template<typename _Tp>
00166 template<_GLIBCXX_TEMPLATE_PARAMS>
00167   typename result_of<
00168    typename reference_wrapper<_Tp>::_M_func_type(_GLIBCXX_TEMPLATE_ARGS)>::type
00169   reference_wrapper<_Tp>::operator()(_GLIBCXX_REF_PARAMS) const
00170   {
00171     return __invoke(get(), _GLIBCXX_ARGS);
00172   }
00173 #endif
00174 
00175 #if _GLIBCXX_NUM_ARGS > 0
00176 template<typename _Res, typename _Class _GLIBCXX_COMMA_SHIFTED
00177          _GLIBCXX_TEMPLATE_PARAMS_SHIFTED>
00178   class _Mem_fn<_Res (_Class::*)(_GLIBCXX_TEMPLATE_ARGS_SHIFTED)>
00179 #if _GLIBCXX_NUM_ARGS == 1
00180   : public unary_function<_Class*, _Res>
00181 #elif _GLIBCXX_NUM_ARGS == 2
00182     : public binary_function<_Class*, _T1, _Res>
00183 #endif
00184   {
00185     typedef _Res (_Class::*_Functor)(_GLIBCXX_TEMPLATE_ARGS_SHIFTED);
00186 
00187     template<typename _Tp>
00188       _Res
00189       _M_call(_Tp& __object, const volatile _Class * _GLIBCXX_COMMA_SHIFTED
00190               _GLIBCXX_PARAMS_SHIFTED) const
00191       { return (__object.*__pmf)(_GLIBCXX_ARGS_SHIFTED); }
00192 
00193     template<typename _Tp>
00194       _Res
00195       _M_call(_Tp& __ptr, const volatile void * _GLIBCXX_COMMA_SHIFTED
00196               _GLIBCXX_PARAMS_SHIFTED) const
00197       {  return ((*__ptr).*__pmf)(_GLIBCXX_ARGS_SHIFTED); }
00198 
00199   public:
00200     typedef _Res result_type;
00201 
00202     explicit _Mem_fn(_Functor __pf) : __pmf(__pf) { }
00203 
00204     // Handle objects
00205     _Res
00206     operator()(_Class& __object _GLIBCXX_COMMA_SHIFTED
00207                _GLIBCXX_PARAMS_SHIFTED) const
00208     { return (__object.*__pmf)(_GLIBCXX_ARGS_SHIFTED); }
00209 
00210     // Handle pointers
00211     _Res
00212     operator()(_Class* __object _GLIBCXX_COMMA_SHIFTED
00213                _GLIBCXX_PARAMS_SHIFTED) const
00214     { return (__object->*__pmf)(_GLIBCXX_ARGS_SHIFTED); }
00215 
00216     // Handle smart pointers, references and pointers to derived
00217     template<typename _Tp>
00218       _Res
00219       operator()(_Tp& __object _GLIBCXX_COMMA_SHIFTED
00220                  _GLIBCXX_PARAMS_SHIFTED) const
00221       {
00222         return _M_call(__object, &__object _GLIBCXX_COMMA_SHIFTED
00223                        _GLIBCXX_ARGS_SHIFTED);
00224       }
00225 
00226   private:
00227     _Functor __pmf;
00228   };
00229 
00230 template<typename _Res, typename _Class _GLIBCXX_COMMA_SHIFTED
00231          _GLIBCXX_TEMPLATE_PARAMS_SHIFTED>
00232   class _Mem_fn<_Res (_Class::*)(_GLIBCXX_TEMPLATE_ARGS_SHIFTED) const>
00233 #if _GLIBCXX_NUM_ARGS == 1
00234   : public unary_function<const _Class*, _Res>
00235 #elif _GLIBCXX_NUM_ARGS == 2
00236     : public binary_function<const _Class*, _T1, _Res>
00237 #endif
00238   {
00239     typedef _Res (_Class::*_Functor)(_GLIBCXX_TEMPLATE_ARGS_SHIFTED) const;
00240 
00241      template<typename _Tp>
00242       _Res
00243       _M_call(_Tp& __object, const volatile _Class * _GLIBCXX_COMMA_SHIFTED
00244               _GLIBCXX_PARAMS_SHIFTED) const
00245       { return (__object.*__pmf)(_GLIBCXX_ARGS_SHIFTED); }
00246 
00247     template<typename _Tp>
00248       _Res
00249       _M_call(_Tp& __ptr, const volatile void * _GLIBCXX_COMMA_SHIFTED
00250               _GLIBCXX_PARAMS_SHIFTED) const
00251       {  return ((*__ptr).*__pmf)(_GLIBCXX_ARGS_SHIFTED); }
00252 
00253   public:
00254     typedef _Res result_type;
00255 
00256     explicit _Mem_fn(_Functor __pf) : __pmf(__pf) { }
00257 
00258     // Handle objects
00259     _Res
00260     operator()(const _Class& __object _GLIBCXX_COMMA_SHIFTED
00261                _GLIBCXX_PARAMS_SHIFTED) const
00262     { return (__object.*__pmf)(_GLIBCXX_ARGS_SHIFTED); }
00263 
00264     // Handle pointers
00265     _Res
00266     operator()(const _Class* __object _GLIBCXX_COMMA_SHIFTED
00267                _GLIBCXX_PARAMS_SHIFTED) const
00268     { return (__object->*__pmf)(_GLIBCXX_ARGS_SHIFTED); }
00269 
00270     // Handle smart pointers, references and pointers to derived
00271     template<typename _Tp>
00272       _Res
00273       operator()(_Tp& __object _GLIBCXX_COMMA_SHIFTED
00274                  _GLIBCXX_PARAMS_SHIFTED) const
00275       {
00276         return _M_call(__object, &__object _GLIBCXX_COMMA_SHIFTED
00277                        _GLIBCXX_ARGS_SHIFTED);
00278       }
00279 
00280   private:
00281     _Functor __pmf;
00282   };
00283 
00284 template<typename _Res, typename _Class _GLIBCXX_COMMA_SHIFTED
00285          _GLIBCXX_TEMPLATE_PARAMS_SHIFTED>
00286   class _Mem_fn<_Res (_Class::*)(_GLIBCXX_TEMPLATE_ARGS_SHIFTED) volatile>
00287 #if _GLIBCXX_NUM_ARGS == 1
00288   : public unary_function<volatile _Class*, _Res>
00289 #elif _GLIBCXX_NUM_ARGS == 2
00290     : public binary_function<volatile _Class*, _T1, _Res>
00291 #endif
00292   {
00293     typedef _Res (_Class::*_Functor)(_GLIBCXX_TEMPLATE_ARGS_SHIFTED) volatile;
00294 
00295     template<typename _Tp>
00296       _Res
00297       _M_call(_Tp& __object, const volatile _Class * _GLIBCXX_COMMA_SHIFTED
00298               _GLIBCXX_PARAMS_SHIFTED) const
00299       { return (__object.*__pmf)(_GLIBCXX_ARGS_SHIFTED); }
00300 
00301     template<typename _Tp>
00302       _Res
00303       _M_call(_Tp& __ptr, const volatile void * _GLIBCXX_COMMA_SHIFTED
00304               _GLIBCXX_PARAMS_SHIFTED) const
00305       {  return ((*__ptr).*__pmf)(_GLIBCXX_ARGS_SHIFTED); }
00306 
00307   public:
00308     typedef _Res result_type;
00309 
00310     explicit _Mem_fn(_Functor __pf) : __pmf(__pf) { }
00311 
00312     // Handle objects
00313     _Res
00314     operator()(volatile _Class& __object _GLIBCXX_COMMA_SHIFTED
00315                _GLIBCXX_PARAMS_SHIFTED) const
00316     { return (__object.*__pmf)(_GLIBCXX_ARGS_SHIFTED); }
00317 
00318     // Handle pointers
00319     _Res
00320     operator()(volatile _Class* __object _GLIBCXX_COMMA_SHIFTED
00321                _GLIBCXX_PARAMS_SHIFTED) const
00322     { return (__object->*__pmf)(_GLIBCXX_ARGS_SHIFTED); }
00323 
00324     // Handle smart pointers, references and pointers to derived
00325     template<typename _Tp>
00326       _Res
00327       operator()(_Tp& __object _GLIBCXX_COMMA_SHIFTED
00328                  _GLIBCXX_PARAMS_SHIFTED) const
00329       {
00330         return _M_call(__object, &__object _GLIBCXX_COMMA_SHIFTED
00331                        _GLIBCXX_ARGS_SHIFTED);
00332       }
00333   private:
00334     _Functor __pmf;
00335   };
00336 
00337 template<typename _Res, typename _Class _GLIBCXX_COMMA_SHIFTED
00338          _GLIBCXX_TEMPLATE_PARAMS_SHIFTED>
00339   class _Mem_fn<_Res(_Class::*)(_GLIBCXX_TEMPLATE_ARGS_SHIFTED) const volatile>
00340 #if _GLIBCXX_NUM_ARGS == 1
00341   : public unary_function<const volatile _Class*, _Res>
00342 #elif _GLIBCXX_NUM_ARGS == 2
00343     : public binary_function<const volatile _Class*, _T1, _Res>
00344 #endif
00345   {
00346     typedef _Res (_Class::*_Functor)(_GLIBCXX_TEMPLATE_ARGS_SHIFTED)
00347               const volatile;
00348 
00349     template<typename _Tp>
00350       _Res
00351       _M_call(_Tp& __object, const volatile _Class * _GLIBCXX_COMMA_SHIFTED
00352               _GLIBCXX_PARAMS_SHIFTED) const
00353       { return (__object.*__pmf)(_GLIBCXX_ARGS_SHIFTED); }
00354 
00355     template<typename _Tp>
00356       _Res
00357       _M_call(_Tp& __ptr, const volatile void * _GLIBCXX_COMMA_SHIFTED
00358               _GLIBCXX_PARAMS_SHIFTED) const
00359       {  return ((*__ptr).*__pmf)(_GLIBCXX_ARGS_SHIFTED); }
00360 
00361   public:
00362     typedef _Res result_type;
00363 
00364     explicit _Mem_fn(_Functor __pf) : __pmf(__pf) { }
00365 
00366     // Handle objects
00367     _Res
00368     operator()(const volatile _Class& __object _GLIBCXX_COMMA_SHIFTED
00369                _GLIBCXX_PARAMS_SHIFTED) const
00370     { return (__object.*__pmf)(_GLIBCXX_ARGS_SHIFTED); }
00371 
00372     // Handle pointers
00373     _Res
00374     operator()(const volatile _Class* __object _GLIBCXX_COMMA_SHIFTED
00375                _GLIBCXX_PARAMS_SHIFTED) const
00376     { return (__object->*__pmf)(_GLIBCXX_ARGS_SHIFTED); }
00377 
00378     // Handle smart pointers, references and pointers to derived
00379     template<typename _Tp>
00380       _Res
00381       operator()(_Tp& __object _GLIBCXX_COMMA_SHIFTED
00382                  _GLIBCXX_PARAMS_SHIFTED) const
00383       {
00384         return _M_call(__object, &__object _GLIBCXX_COMMA_SHIFTED
00385                        _GLIBCXX_ARGS_SHIFTED);
00386       }
00387 
00388   private:
00389     _Functor __pmf;
00390   };
00391 #endif
00392 
00393 #if _GLIBCXX_NUM_ARGS > 0
00394 namespace placeholders
00395 {
00396 namespace
00397 {
00398    _Placeholder<_GLIBCXX_NUM_ARGS> _GLIBCXX_JOIN(_,_GLIBCXX_NUM_ARGS);
00399 }
00400 }
00401 #endif
00402 
00403 template<typename _Functor _GLIBCXX_COMMA _GLIBCXX_TEMPLATE_PARAMS>
00404 class _Bind<_Functor(_GLIBCXX_TEMPLATE_ARGS)>
00405   : public _Weak_result_type<_Functor>
00406 {
00407   typedef _Bind __self_type;
00408 
00409   _Functor _M_f;
00410   _GLIBCXX_BIND_MEMBERS
00411 
00412  public:
00413 #if _GLIBCXX_NUM_ARGS == 0
00414   explicit
00415 #endif
00416   _Bind(_Functor __f _GLIBCXX_COMMA _GLIBCXX_PARAMS)
00417     : _M_f(__f) _GLIBCXX_COMMA _GLIBCXX_BIND_MEMBERS_INIT { }
00418 
00419 #define _GLIBCXX_BIND_REPEAT_HEADER <tr1/bind_iterate.h>
00420 #include <tr1/bind_repeat.h>
00421 #undef _GLIBCXX_BIND_REPEAT_HEADER
00422 };
00423 
00424 template<typename _Result, typename _Functor
00425          _GLIBCXX_COMMA _GLIBCXX_TEMPLATE_PARAMS>
00426 class _Bind_result<_Result, _Functor(_GLIBCXX_TEMPLATE_ARGS)>
00427 {
00428   _Functor _M_f;
00429   _GLIBCXX_BIND_MEMBERS
00430 
00431  public:
00432   typedef _Result result_type;
00433 
00434 #if _GLIBCXX_NUM_ARGS == 0
00435   explicit
00436 #endif
00437   _Bind_result(_Functor __f _GLIBCXX_COMMA _GLIBCXX_PARAMS)
00438     : _M_f(__f) _GLIBCXX_COMMA _GLIBCXX_BIND_MEMBERS_INIT { }
00439 
00440 #define _GLIBCXX_BIND_REPEAT_HEADER <tr1/bind_iterate.h>
00441 #define _GLIBCXX_BIND_HAS_RESULT_TYPE
00442 #include <tr1/bind_repeat.h>
00443 #undef _GLIBCXX_BIND_HAS_RESULT_TYPE
00444 #undef _GLIBCXX_BIND_REPEAT_HEADER
00445 };
00446 
00447 // Handle arbitrary function objects
00448 template<typename _Functor _GLIBCXX_COMMA _GLIBCXX_TEMPLATE_PARAMS>
00449 inline
00450 _Bind<typename _Maybe_wrap_member_pointer<_Functor>::type
00451         (_GLIBCXX_TEMPLATE_ARGS)>
00452 bind(_Functor __f _GLIBCXX_COMMA _GLIBCXX_PARAMS)
00453 {
00454   typedef _Maybe_wrap_member_pointer<_Functor> __maybe_type;
00455   typedef typename __maybe_type::type __functor_type;
00456   typedef _Bind<__functor_type(_GLIBCXX_TEMPLATE_ARGS)> __result_type;
00457   return __result_type(__maybe_type::__do_wrap(__f)
00458                        _GLIBCXX_COMMA _GLIBCXX_ARGS);
00459 }
00460 
00461 template<typename _Result, typename _Functor
00462          _GLIBCXX_COMMA _GLIBCXX_TEMPLATE_PARAMS>
00463 inline
00464 _Bind_result<_Result,
00465              typename _Maybe_wrap_member_pointer<_Functor>::type
00466                (_GLIBCXX_TEMPLATE_ARGS)>
00467 bind(_Functor __f _GLIBCXX_COMMA _GLIBCXX_PARAMS)
00468 {
00469   typedef _Maybe_wrap_member_pointer<_Functor> __maybe_type;
00470   typedef typename __maybe_type::type __functor_type;
00471   typedef _Bind_result<_Result, __functor_type(_GLIBCXX_TEMPLATE_ARGS)>
00472     __result_type;
00473   return __result_type(__maybe_type::__do_wrap(__f)
00474                        _GLIBCXX_COMMA _GLIBCXX_ARGS);
00475 }
00476 
00477 template<typename _Res, typename _Functor _GLIBCXX_COMMA
00478          _GLIBCXX_TEMPLATE_PARAMS>
00479 class _Function_handler<_Res(_GLIBCXX_TEMPLATE_ARGS), _Functor>
00480   : public _Function_base::_Base_manager<_Functor>
00481 {
00482   typedef _Function_base::_Base_manager<_Functor> _Base;
00483 
00484  public:
00485   static _Res
00486   _M_invoke(const _Any_data& __functor _GLIBCXX_COMMA _GLIBCXX_PARAMS)
00487   {
00488     return (*_Base::_M_get_pointer(__functor))(_GLIBCXX_ARGS);
00489   }
00490 };
00491 
00492 template<typename _Functor _GLIBCXX_COMMA _GLIBCXX_TEMPLATE_PARAMS>
00493 class _Function_handler<void(_GLIBCXX_TEMPLATE_ARGS), _Functor>
00494   : public _Function_base::_Base_manager<_Functor>
00495 {
00496   typedef _Function_base::_Base_manager<_Functor> _Base;
00497 
00498  public:
00499   static void
00500   _M_invoke(const _Any_data& __functor _GLIBCXX_COMMA _GLIBCXX_PARAMS)
00501   {
00502     (*_Base::_M_get_pointer(__functor))(_GLIBCXX_ARGS);
00503   }
00504 };
00505 
00506 template<typename _Res, typename _Functor _GLIBCXX_COMMA
00507          _GLIBCXX_TEMPLATE_PARAMS>
00508 class _Function_handler<_Res(_GLIBCXX_TEMPLATE_ARGS),
00509                         reference_wrapper<_Functor> >
00510   : public _Function_base::_Ref_manager<_Functor>
00511 {
00512   typedef _Function_base::_Ref_manager<_Functor> _Base;
00513 
00514  public:
00515   static _Res
00516   _M_invoke(const _Any_data& __functor _GLIBCXX_COMMA _GLIBCXX_PARAMS)
00517   {
00518     return __callable_functor(**_Base::_M_get_pointer(__functor))
00519              (_GLIBCXX_ARGS);
00520   }
00521 };
00522 
00523 template<typename _Functor _GLIBCXX_COMMA _GLIBCXX_TEMPLATE_PARAMS>
00524 class _Function_handler<void(_GLIBCXX_TEMPLATE_ARGS),
00525                         reference_wrapper<_Functor> >
00526   : public _Function_base::_Ref_manager<_Functor>
00527 {
00528   typedef _Function_base::_Ref_manager<_Functor> _Base;
00529 
00530  public:
00531   static void
00532   _M_invoke(const _Any_data& __functor _GLIBCXX_COMMA _GLIBCXX_PARAMS)
00533   {
00534     __callable_functor(**_Base::_M_get_pointer(__functor))(_GLIBCXX_ARGS);
00535   }
00536 };
00537 
00538 template<typename _Class, typename _Member, typename _Res
00539          _GLIBCXX_COMMA _GLIBCXX_TEMPLATE_PARAMS>
00540 class _Function_handler<_Res(_GLIBCXX_TEMPLATE_ARGS), _Member _Class::*>
00541   : public _Function_handler<void(_GLIBCXX_TEMPLATE_ARGS), _Member _Class::*>
00542 {
00543   typedef _Function_handler<void(_GLIBCXX_TEMPLATE_ARGS), _Member _Class::*>
00544     _Base;
00545 
00546  public:
00547   static _Res
00548   _M_invoke(const _Any_data& __functor _GLIBCXX_COMMA _GLIBCXX_PARAMS)
00549   {
00550     return std::tr1::mem_fn(_Base::_M_get_pointer(__functor)->__value)
00551              (_GLIBCXX_ARGS);
00552   }
00553 };
00554 
00555 template<typename _Class, typename _Member
00556          _GLIBCXX_COMMA _GLIBCXX_TEMPLATE_PARAMS>
00557 class _Function_handler<void(_GLIBCXX_TEMPLATE_ARGS), _Member _Class::*>
00558   : public _Function_base::_Base_manager<
00559              _Simple_type_wrapper< _Member _Class::* > >
00560 {
00561   typedef _Member _Class::* _Functor;
00562   typedef _Simple_type_wrapper< _Functor > _Wrapper;
00563   typedef _Function_base::_Base_manager<_Wrapper> _Base;
00564 
00565  public:
00566   static bool
00567   _M_manager(_Any_data& __dest, const _Any_data& __source,
00568              _Manager_operation __op)
00569   {
00570     switch (__op) {
00571     case __get_type_info:
00572       __dest._M_access<const type_info*>() = &typeid(_Functor);
00573       break;
00574 
00575     case __get_functor_ptr:
00576       __dest._M_access<_Functor*>() =
00577         &_Base::_M_get_pointer(__source)->__value;
00578       break;
00579 
00580     default:
00581       _Base::_M_manager(__dest, __source, __op);
00582     }
00583     return false;
00584   }
00585 
00586   static void
00587   _M_invoke(const _Any_data& __functor _GLIBCXX_COMMA _GLIBCXX_PARAMS)
00588   {
00589     std::tr1::mem_fn(_Base::_M_get_pointer(__functor)->__value)
00590       (_GLIBCXX_ARGS);
00591   }
00592 };
00593 
00594 template<typename _Res _GLIBCXX_COMMA _GLIBCXX_TEMPLATE_PARAMS>
00595 class function<_Res(_GLIBCXX_TEMPLATE_ARGS)>
00596 #if _GLIBCXX_NUM_ARGS == 1
00597   : public unary_function<_T1, _Res>, private _Function_base
00598 #elif _GLIBCXX_NUM_ARGS == 2
00599   : public binary_function<_T1, _T2, _Res>, private _Function_base
00600 #else
00601   : private _Function_base
00602 #endif
00603 {
00609   struct _Hidden_type
00610   {
00611     _Hidden_type* _M_bool;
00612   };
00613 
00619   typedef _Hidden_type* _Hidden_type::* _Safe_bool;
00620 
00621   typedef _Res _Signature_type(_GLIBCXX_TEMPLATE_ARGS);
00622 
00623   struct _Useless {};
00624 
00625  public:
00626   typedef _Res result_type;
00627 
00628   // [3.7.2.1] construct/copy/destroy
00629 
00634   function() : _Function_base() { }
00635 
00640   function(_M_clear_type*) : _Function_base() { }
00641 
00650   function(const function& __x);
00651 
00668   template<typename _Functor>
00669     function(_Functor __f,
00670              typename __enable_if<_Useless,
00671                                   !is_integral<_Functor>::value>::__type
00672                = _Useless());
00673 
00686   function& operator=(const function& __x)
00687     {
00688       function(__x).swap(*this);
00689       return *this;
00690     }
00691 
00699   function& operator=(_M_clear_type*)
00700     {
00701       if (_M_manager) {
00702         _M_manager(_M_functor, _M_functor, __destroy_functor);
00703         _M_manager = 0;
00704         _M_invoker = 0;
00705       }
00706       return *this;
00707     }
00708 
00725   template<typename _Functor>
00726     typename __enable_if<function&, !is_integral<_Functor>::value>::__type
00727     operator=(_Functor __f)
00728     {
00729       function(__f).swap(*this);
00730       return *this;
00731     }
00732 
00733   // [3.7.2.2] function modifiers
00734 
00742   void swap(function& __x)
00743   {
00744     _Any_data __old_functor = _M_functor;
00745     _M_functor = __x._M_functor;
00746     __x._M_functor = __old_functor;
00747     _Manager_type __old_manager = _M_manager;
00748     _M_manager = __x._M_manager;
00749     __x._M_manager = __old_manager;
00750     _Invoker_type __old_invoker = _M_invoker;
00751     _M_invoker = __x._M_invoker;
00752     __x._M_invoker = __old_invoker;
00753   }
00754 
00755   // [3.7.2.3] function capacity
00756 
00765   operator _Safe_bool() const
00766     {
00767       if (_M_empty())
00768         {
00769           return 0;
00770         }
00771       else
00772         {
00773           return &_Hidden_type::_M_bool;
00774         }
00775     }
00776 
00777   // [3.7.2.4] function invocation
00778 
00787   _Res operator()(_GLIBCXX_PARAMS) const;
00788 
00789   // [3.7.2.5] function target access
00799   const type_info& target_type() const;
00800 
00810   template<typename _Functor>       _Functor* target();
00811 
00815   template<typename _Functor> const _Functor* target() const;
00816 
00817  private:
00818   // [3.7.2.6] undefined operators
00819   template<typename _Function>
00820     void operator==(const function<_Function>&) const;
00821   template<typename _Function>
00822     void operator!=(const function<_Function>&) const;
00823 
00824   typedef _Res (*_Invoker_type)(const _Any_data& _GLIBCXX_COMMA
00825                                 _GLIBCXX_PARAMS);
00826   _Invoker_type _M_invoker;
00827 };
00828 
00829 template<typename _Res _GLIBCXX_COMMA _GLIBCXX_TEMPLATE_PARAMS>
00830   function<_Res(_GLIBCXX_TEMPLATE_ARGS)>::function(const function& __x)
00831     : _Function_base()
00832   {
00833     if (__x) {
00834       _M_invoker = __x._M_invoker;
00835       _M_manager = __x._M_manager;
00836       __x._M_manager(_M_functor, __x._M_functor, __clone_functor);
00837     }
00838   }
00839 
00840 template<typename _Res _GLIBCXX_COMMA _GLIBCXX_TEMPLATE_PARAMS>
00841 template<typename _Functor>
00842   function<_Res(_GLIBCXX_TEMPLATE_ARGS)>
00843   ::function(_Functor __f,
00844              typename __enable_if<_Useless,
00845                                   !is_integral<_Functor>::value>::__type)
00846     : _Function_base()
00847 {
00848   typedef _Function_handler<_Signature_type, _Functor> _My_handler;
00849   if (_My_handler::_M_not_empty_function(__f)) {
00850     _M_invoker = &_My_handler::_M_invoke;
00851     _M_manager = &_My_handler::_M_manager;
00852     _My_handler::_M_init_functor(_M_functor, __f);
00853   }
00854 }
00855 
00856 template<typename _Res _GLIBCXX_COMMA _GLIBCXX_TEMPLATE_PARAMS>
00857   _Res
00858   function<_Res(_GLIBCXX_TEMPLATE_ARGS)>::operator()(_GLIBCXX_PARAMS) const
00859   {
00860     if (_M_empty())
00861       {
00862 #if __EXCEPTIONS
00863         throw bad_function_call();
00864 #else
00865         std::abort();
00866 #endif
00867       }
00868     return _M_invoker(_M_functor _GLIBCXX_COMMA _GLIBCXX_ARGS);
00869   }
00870 
00871 template<typename _Res _GLIBCXX_COMMA _GLIBCXX_TEMPLATE_PARAMS>
00872   const type_info&
00873   function<_Res(_GLIBCXX_TEMPLATE_ARGS)>::target_type() const
00874   {
00875     if (_M_manager)
00876       {
00877         _Any_data __typeinfo_result;
00878         _M_manager(__typeinfo_result, _M_functor, __get_type_info);
00879         return *__typeinfo_result._M_access<const type_info*>();
00880       }
00881     else
00882       {
00883         return typeid(void);
00884       }
00885   }
00886 
00887 template<typename _Res _GLIBCXX_COMMA _GLIBCXX_TEMPLATE_PARAMS>
00888 template<typename _Functor>
00889   _Functor*
00890   function<_Res(_GLIBCXX_TEMPLATE_ARGS)>::target()
00891   {
00892     if (typeid(_Functor) == target_type() && _M_manager)
00893       {
00894         _Any_data __ptr;
00895         if (_M_manager(__ptr, _M_functor, __get_functor_ptr)
00896             && !is_const<_Functor>::value)
00897           return 0;
00898         else
00899           return __ptr._M_access<_Functor*>();
00900       }
00901     else
00902       {
00903         return 0;
00904       }
00905   }
00906 
00907 template<typename _Res _GLIBCXX_COMMA _GLIBCXX_TEMPLATE_PARAMS>
00908 template<typename _Functor>
00909   const _Functor*
00910   function<_Res(_GLIBCXX_TEMPLATE_ARGS)>::target() const
00911   {
00912     if (typeid(_Functor) == target_type() && _M_manager)
00913       {
00914         _Any_data __ptr;
00915         _M_manager(__ptr, _M_functor, __get_functor_ptr);
00916         return __ptr._M_access<const _Functor*>();
00917       }
00918     else
00919       {
00920         return 0;
00921       }
00922   }
00923 

Generated on Tue Feb 2 16:55:58 2010 for GNU C++ STL by  doxygen 1.4.7