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 
00031 /** @file tr1/functional_iterate.h
00032  *  This is an internal header file, included by other library headers.
00033  *  You should not attempt to use it directly.
00034  */
00035 
00036 namespace std
00037 {
00038 _GLIBCXX_BEGIN_NAMESPACE(tr1)
00039 
00040 template<typename _Res _GLIBCXX_COMMA _GLIBCXX_TEMPLATE_PARAMS>
00041   struct _Weak_result_type_impl<_Res(_GLIBCXX_TEMPLATE_ARGS)>
00042   {
00043     typedef _Res result_type;
00044   };
00045 
00046 template<typename _Res _GLIBCXX_COMMA _GLIBCXX_TEMPLATE_PARAMS>
00047   struct _Weak_result_type_impl<_Res (&)(_GLIBCXX_TEMPLATE_ARGS)>
00048   {
00049     typedef _Res result_type;
00050   };
00051 
00052 template<typename _Res _GLIBCXX_COMMA _GLIBCXX_TEMPLATE_PARAMS>
00053   struct _Weak_result_type_impl<_Res (*)(_GLIBCXX_TEMPLATE_ARGS)>
00054   {
00055     typedef _Res result_type;
00056   };
00057 
00058 #if _GLIBCXX_NUM_ARGS > 0
00059 template<typename _Res, typename _Class _GLIBCXX_COMMA_SHIFTED
00060          _GLIBCXX_TEMPLATE_PARAMS_SHIFTED>
00061   struct _Weak_result_type_impl<
00062            _Res (_Class::*)(_GLIBCXX_TEMPLATE_ARGS_SHIFTED)>
00063   {
00064     typedef _Res result_type;
00065   };
00066 
00067 template<typename _Res, typename _Class _GLIBCXX_COMMA_SHIFTED
00068          _GLIBCXX_TEMPLATE_PARAMS_SHIFTED>
00069   struct _Weak_result_type_impl<
00070            _Res (_Class::*)(_GLIBCXX_TEMPLATE_ARGS_SHIFTED) const>
00071   {
00072     typedef _Res result_type;
00073   };
00074 
00075 template<typename _Res, typename _Class _GLIBCXX_COMMA_SHIFTED
00076          _GLIBCXX_TEMPLATE_PARAMS_SHIFTED>
00077   struct _Weak_result_type_impl<
00078            _Res (_Class::*)(_GLIBCXX_TEMPLATE_ARGS_SHIFTED) volatile>
00079   {
00080     typedef _Res result_type;
00081   };
00082 
00083 template<typename _Res, typename _Class _GLIBCXX_COMMA_SHIFTED
00084          _GLIBCXX_TEMPLATE_PARAMS_SHIFTED>
00085   struct _Weak_result_type_impl<
00086            _Res (_Class::*)(_GLIBCXX_TEMPLATE_ARGS_SHIFTED) const volatile>
00087   {
00088     typedef _Res result_type;
00089   };
00090 #endif
00091 
00092 template<typename _Functor _GLIBCXX_COMMA _GLIBCXX_TEMPLATE_PARAMS>
00093   class result_of<_Functor(_GLIBCXX_TEMPLATE_ARGS)>
00094     : public _Result_of_impl<
00095                _Has_result_type<_Weak_result_type<_Functor> >::value,
00096              _Functor(_GLIBCXX_TEMPLATE_ARGS)>
00097   { };
00098 
00099 template<typename _Functor _GLIBCXX_COMMA _GLIBCXX_TEMPLATE_PARAMS>
00100   struct _Result_of_impl<true, _Functor(_GLIBCXX_TEMPLATE_ARGS)>
00101   {
00102     typedef typename _Weak_result_type<_Functor>::result_type type;
00103   };
00104 
00105 template<typename _Functor _GLIBCXX_COMMA _GLIBCXX_TEMPLATE_PARAMS>
00106   struct _Result_of_impl<false, _Functor(_GLIBCXX_TEMPLATE_ARGS)>
00107   {
00108 #if _GLIBCXX_NUM_ARGS > 0
00109     typedef typename _Functor
00110               ::template result<_Functor(_GLIBCXX_TEMPLATE_ARGS)>::type type;
00111 #else
00112     typedef void type;
00113 #endif
00114   };
00115 
00116 /**
00117  * @if maint
00118  * Invoke a function object, which may be either a member pointer or a
00119  * function object. The first parameter will tell which.
00120  * @endif
00121  */
00122 template<typename _Functor _GLIBCXX_COMMA _GLIBCXX_TEMPLATE_PARAMS>
00123   inline
00124   typename __gnu_cxx::__enable_if<(!is_member_pointer<_Functor>::value
00125             && !is_function<_Functor>::value
00126               && !is_function<typename remove_pointer<_Functor>::type>::value),
00127            typename result_of<_Functor(_GLIBCXX_TEMPLATE_ARGS)>::type>::__type
00128   __invoke(_Functor& __f _GLIBCXX_COMMA _GLIBCXX_REF_PARAMS)
00129   {
00130     return __f(_GLIBCXX_ARGS);
00131   }
00132 
00133 #if _GLIBCXX_NUM_ARGS > 0
00134 template<typename _Functor _GLIBCXX_COMMA _GLIBCXX_TEMPLATE_PARAMS>
00135   inline
00136   typename __gnu_cxx::__enable_if<(is_member_pointer<_Functor>::value
00137             && !is_function<_Functor>::value
00138               && !is_function<typename remove_pointer<_Functor>::type>::value),
00139              typename result_of<_Functor(_GLIBCXX_TEMPLATE_ARGS)>::type
00140            >::__type
00141   __invoke(_Functor& __f _GLIBCXX_COMMA _GLIBCXX_REF_PARAMS)
00142   {
00143     return mem_fn(__f)(_GLIBCXX_ARGS);
00144   }
00145 #endif
00146 
00147 // To pick up function references (that will become function pointers)
00148 template<typename _Functor _GLIBCXX_COMMA _GLIBCXX_TEMPLATE_PARAMS>
00149   inline
00150   typename __gnu_cxx::__enable_if<(is_pointer<_Functor>::value
00151     && is_function<typename remove_pointer<_Functor>::type>::value),
00152              typename result_of<_Functor(_GLIBCXX_TEMPLATE_ARGS)>::type
00153            >::__type
00154   __invoke(_Functor __f _GLIBCXX_COMMA _GLIBCXX_REF_PARAMS)
00155   {
00156     return __f(_GLIBCXX_ARGS);
00157   }
00158 
00159 /**
00160  * @if maint
00161  * Implementation of reference_wrapper::operator()
00162  * @endif
00163 */
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 } // anonymous namespace
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 {
00604   /**
00605    *  @if maint
00606    *  This class is used to implement the safe_bool idiom.
00607    *  @endif
00608    */
00609   struct _Hidden_type
00610   {
00611     _Hidden_type* _M_bool;
00612   };
00613 
00614   /**
00615    *  @if maint
00616    *  This typedef is used to implement the safe_bool idiom.
00617    *  @endif
00618    */
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 
00630   /**
00631    *  @brief Default construct creates an empty function call wrapper.
00632    *  @post @c !(bool)*this
00633    */
00634   function() : _Function_base() { }
00635 
00636   /**
00637    *  @brief Default construct creates an empty function call wrapper.
00638    *  @post @c !(bool)*this
00639    */
00640   function(_M_clear_type*) : _Function_base() { }
00641 
00642   /**
00643    *  @brief %Function copy constructor.
00644    *  @param x A %function object with identical call signature.
00645    *  @pre @c (bool)*this == (bool)x
00646    *
00647    *  The newly-created %function contains a copy of the target of @a
00648    *  x (if it has one).
00649    */
00650   function(const function& __x);
00651 
00652   /**
00653    *  @brief Builds a %function that targets a copy of the incoming
00654    *  function object.
00655    *  @param f A %function object that is callable with parameters of
00656    *  type @c T1, @c T2, ..., @c TN and returns a value convertible
00657    *  to @c Res.
00658    *
00659    *  The newly-created %function object will target a copy of @a
00660    *  f. If @a f is @c reference_wrapper<F>, then this function
00661    *  object will contain a reference to the function object @c
00662    *  f.get(). If @a f is a NULL function pointer or NULL
00663    *  pointer-to-member, the newly-created object will be empty.
00664    *
00665    *  If @a f is a non-NULL function pointer or an object of type @c
00666    *  reference_wrapper<F>, this function will not throw.
00667    */
00668   template<typename _Functor>
00669     function(_Functor __f,
00670              typename __gnu_cxx::__enable_if<!is_integral<_Functor>::value, _Useless>::__type = _Useless());
00671 
00672   /**
00673    *  @brief %Function assignment operator.
00674    *  @param x A %function with identical call signature.
00675    *  @post @c (bool)*this == (bool)x
00676    *  @returns @c *this
00677    *
00678    *  The target of @a x is copied to @c *this. If @a x has no
00679    *  target, then @c *this will be empty.
00680    *
00681    *  If @a x targets a function pointer or a reference to a function
00682    *  object, then this operation will not throw an exception.
00683    */
00684   function& operator=(const function& __x)
00685     {
00686       function(__x).swap(*this);
00687       return *this;
00688     }
00689 
00690   /**
00691    *  @brief %Function assignment to zero.
00692    *  @post @c !(bool)*this
00693    *  @returns @c *this
00694    *
00695    *  The target of @a *this is deallocated, leaving it empty.
00696    */
00697   function& operator=(_M_clear_type*)
00698     {
00699       if (_M_manager) {
00700         _M_manager(_M_functor, _M_functor, __destroy_functor);
00701         _M_manager = 0;
00702         _M_invoker = 0;
00703       }
00704       return *this;
00705     }
00706 
00707   /**
00708    *  @brief %Function assignment to a new target.
00709    *  @param f A %function object that is callable with parameters of
00710    *  type @c T1, @c T2, ..., @c TN and returns a value convertible
00711    *  to @c Res.
00712    *  @return @c *this
00713    *
00714    *  This  %function object wrapper will target a copy of @a
00715    *  f. If @a f is @c reference_wrapper<F>, then this function
00716    *  object will contain a reference to the function object @c
00717    *  f.get(). If @a f is a NULL function pointer or NULL
00718    *  pointer-to-member, @c this object will be empty.
00719    *
00720    *  If @a f is a non-NULL function pointer or an object of type @c
00721    *  reference_wrapper<F>, this function will not throw.
00722    */
00723   template<typename _Functor>
00724     typename __gnu_cxx::__enable_if<!is_integral<_Functor>::value, function&>::__type
00725     operator=(_Functor __f)
00726     {
00727       function(__f).swap(*this);
00728       return *this;
00729     }
00730 
00731   // [3.7.2.2] function modifiers
00732 
00733   /**
00734    *  @brief Swap the targets of two %function objects.
00735    *  @param f A %function with identical call signature.
00736    *
00737    *  Swap the targets of @c this function object and @a f. This
00738    *  function will not throw an exception.
00739    */
00740   void swap(function& __x)
00741   {
00742     _Any_data __old_functor = _M_functor;
00743     _M_functor = __x._M_functor;
00744     __x._M_functor = __old_functor;
00745     _Manager_type __old_manager = _M_manager;
00746     _M_manager = __x._M_manager;
00747     __x._M_manager = __old_manager;
00748     _Invoker_type __old_invoker = _M_invoker;
00749     _M_invoker = __x._M_invoker;
00750     __x._M_invoker = __old_invoker;
00751   }
00752 
00753   // [3.7.2.3] function capacity
00754 
00755   /**
00756    *  @brief Determine if the %function wrapper has a target.
00757    *
00758    *  @return @c true when this %function object contains a target,
00759    *  or @c false when it is empty.
00760    *
00761    *  This function will not throw an exception.
00762    */
00763   operator _Safe_bool() const
00764     {
00765       if (_M_empty())
00766         {
00767           return 0;
00768         }
00769       else
00770         {
00771           return &_Hidden_type::_M_bool;
00772         }
00773     }
00774 
00775   // [3.7.2.4] function invocation
00776 
00777   /**
00778    *  @brief Invokes the function targeted by @c *this.
00779    *  @returns the result of the target.
00780    *  @throws bad_function_call when @c !(bool)*this
00781    *
00782    *  The function call operator invokes the target function object
00783    *  stored by @c this.
00784    */
00785   _Res operator()(_GLIBCXX_PARAMS) const;
00786 
00787   // [3.7.2.5] function target access
00788   /**
00789    *  @brief Determine the type of the target of this function object
00790    *  wrapper.
00791    *
00792    *  @returns the type identifier of the target function object, or
00793    *  @c typeid(void) if @c !(bool)*this.
00794    *
00795    *  This function will not throw an exception.
00796    */
00797   const type_info& target_type() const;
00798 
00799   /**
00800    *  @brief Access the stored target function object.
00801    *
00802    *  @return Returns a pointer to the stored target function object,
00803    *  if @c typeid(Functor).equals(target_type()); otherwise, a NULL
00804    *  pointer.
00805    *
00806    * This function will not throw an exception.
00807    */
00808   template<typename _Functor>       _Functor* target();
00809 
00810   /**
00811    *  @overload
00812    */
00813   template<typename _Functor> const _Functor* target() const;
00814 
00815  private:
00816   // [3.7.2.6] undefined operators
00817   template<typename _Function>
00818     void operator==(const function<_Function>&) const;
00819   template<typename _Function>
00820     void operator!=(const function<_Function>&) const;
00821 
00822   typedef _Res (*_Invoker_type)(const _Any_data& _GLIBCXX_COMMA
00823                                 _GLIBCXX_PARAMS);
00824   _Invoker_type _M_invoker;
00825 };
00826 
00827 template<typename _Res _GLIBCXX_COMMA _GLIBCXX_TEMPLATE_PARAMS>
00828   function<_Res(_GLIBCXX_TEMPLATE_ARGS)>::function(const function& __x)
00829     : _Function_base()
00830   {
00831     if (__x) {
00832       _M_invoker = __x._M_invoker;
00833       _M_manager = __x._M_manager;
00834       __x._M_manager(_M_functor, __x._M_functor, __clone_functor);
00835     }
00836   }
00837 
00838 template<typename _Res _GLIBCXX_COMMA _GLIBCXX_TEMPLATE_PARAMS>
00839 template<typename _Functor>
00840   function<_Res(_GLIBCXX_TEMPLATE_ARGS)>
00841   ::function(_Functor __f,
00842         typename __gnu_cxx::__enable_if<!is_integral<_Functor>::value, _Useless>::__type)
00843     : _Function_base()
00844 {
00845   typedef _Function_handler<_Signature_type, _Functor> _My_handler;
00846   if (_My_handler::_M_not_empty_function(__f)) {
00847     _M_invoker = &_My_handler::_M_invoke;
00848     _M_manager = &_My_handler::_M_manager;
00849     _My_handler::_M_init_functor(_M_functor, __f);
00850   }
00851 }
00852 
00853 template<typename _Res _GLIBCXX_COMMA _GLIBCXX_TEMPLATE_PARAMS>
00854   _Res
00855   function<_Res(_GLIBCXX_TEMPLATE_ARGS)>::operator()(_GLIBCXX_PARAMS) const
00856   {
00857     if (_M_empty())
00858       {
00859 #if __EXCEPTIONS
00860         throw bad_function_call();
00861 #else
00862         std::abort();
00863 #endif
00864       }
00865     return _M_invoker(_M_functor _GLIBCXX_COMMA _GLIBCXX_ARGS);
00866   }
00867 
00868 template<typename _Res _GLIBCXX_COMMA _GLIBCXX_TEMPLATE_PARAMS>
00869   const type_info&
00870   function<_Res(_GLIBCXX_TEMPLATE_ARGS)>::target_type() const
00871   {
00872     if (_M_manager)
00873       {
00874         _Any_data __typeinfo_result;
00875         _M_manager(__typeinfo_result, _M_functor, __get_type_info);
00876         return *__typeinfo_result._M_access<const type_info*>();
00877       }
00878     else
00879       {
00880         return typeid(void);
00881       }
00882   }
00883 
00884 template<typename _Res _GLIBCXX_COMMA _GLIBCXX_TEMPLATE_PARAMS>
00885 template<typename _Functor>
00886   _Functor*
00887   function<_Res(_GLIBCXX_TEMPLATE_ARGS)>::target()
00888   {
00889     if (typeid(_Functor) == target_type() && _M_manager)
00890       {
00891         _Any_data __ptr;
00892         if (_M_manager(__ptr, _M_functor, __get_functor_ptr)
00893             && !is_const<_Functor>::value)
00894           return 0;
00895         else
00896           return __ptr._M_access<_Functor*>();
00897       }
00898     else
00899       {
00900         return 0;
00901       }
00902   }
00903 
00904 template<typename _Res _GLIBCXX_COMMA _GLIBCXX_TEMPLATE_PARAMS>
00905 template<typename _Functor>
00906   const _Functor*
00907   function<_Res(_GLIBCXX_TEMPLATE_ARGS)>::target() const
00908   {
00909     if (typeid(_Functor) == target_type() && _M_manager)
00910       {
00911         _Any_data __ptr;
00912         _M_manager(__ptr, _M_functor, __get_functor_ptr);
00913         return __ptr._M_access<const _Functor*>();
00914       }
00915     else
00916       {
00917         return 0;
00918       }
00919   }
00920 
00921 _GLIBCXX_END_NAMESPACE
00922 }

Generated on Thu Nov 1 13:11:30 2007 for libstdc++ by  doxygen 1.5.1