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