1 // ------------------------------------------------------------------------------ 2 // Copyright (c) 2000 Cadenza New Zealand Ltd 3 // Distributed under the Boost Software License, Version 1.0. (See accompany- 4 // ing file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) 5 // ------------------------------------------------------------------------------ 6 // Boost functional.hpp header file 7 // See http://www.boost.org/libs/functional for documentation. 8 // ------------------------------------------------------------------------------ 9 // $Id$ 10 // ------------------------------------------------------------------------------ 11 12 #ifndef BOOST_FUNCTIONAL_HPP 13 #define BOOST_FUNCTIONAL_HPP 14 15 #include <boost/config.hpp> 16 #include <boost/call_traits.hpp> 17 #include <functional> 18 19 namespace boost 20 { 21 namespace functional 22 { 23 namespace detail { 24 #if defined(_HAS_AUTO_PTR_ETC) && !_HAS_AUTO_PTR_ETC 25 // std::unary_function and std::binary_function were both removed 26 // in C++17. 27 28 template <typename Arg1, typename Result> 29 struct unary_function 30 { 31 typedef Arg1 argument_type; 32 typedef Result result_type; 33 }; 34 35 template <typename Arg1, typename Arg2, typename Result> 36 struct binary_function 37 { 38 typedef Arg1 first_argument_type; 39 typedef Arg2 second_argument_type; 40 typedef Result result_type; 41 }; 42 #else 43 // Use the standard objects when we have them. 44 45 using std::unary_function; 46 using std::binary_function; 47 #endif 48 } 49 } 50 51 #ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION 52 // -------------------------------------------------------------------------- 53 // The following traits classes allow us to avoid the need for ptr_fun 54 // because the types of arguments and the result of a function can be 55 // deduced. 56 // 57 // In addition to the standard types defined in unary_function and 58 // binary_function, we add 59 // 60 // - function_type, the type of the function or function object itself. 61 // 62 // - param_type, the type that should be used for passing the function or 63 // function object as an argument. 64 // -------------------------------------------------------------------------- 65 namespace detail 66 { 67 template <class Operation> 68 struct unary_traits_imp; 69 70 template <class Operation> 71 struct unary_traits_imp<Operation*> 72 { 73 typedef Operation function_type; 74 typedef const function_type & param_type; 75 typedef typename Operation::result_type result_type; 76 typedef typename Operation::argument_type argument_type; 77 }; 78 79 template <class R, class A> 80 struct unary_traits_imp<R(*)(A)> 81 { 82 typedef R (*function_type)(A); 83 typedef R (*param_type)(A); 84 typedef R result_type; 85 typedef A argument_type; 86 }; 87 88 template <class Operation> 89 struct binary_traits_imp; 90 91 template <class Operation> 92 struct binary_traits_imp<Operation*> 93 { 94 typedef Operation function_type; 95 typedef const function_type & param_type; 96 typedef typename Operation::result_type result_type; 97 typedef typename Operation::first_argument_type first_argument_type; 98 typedef typename Operation::second_argument_type second_argument_type; 99 }; 100 101 template <class R, class A1, class A2> 102 struct binary_traits_imp<R(*)(A1,A2)> 103 { 104 typedef R (*function_type)(A1,A2); 105 typedef R (*param_type)(A1,A2); 106 typedef R result_type; 107 typedef A1 first_argument_type; 108 typedef A2 second_argument_type; 109 }; 110 } // namespace detail 111 112 template <class Operation> 113 struct unary_traits 114 { 115 typedef typename detail::unary_traits_imp<Operation*>::function_type function_type; 116 typedef typename detail::unary_traits_imp<Operation*>::param_type param_type; 117 typedef typename detail::unary_traits_imp<Operation*>::result_type result_type; 118 typedef typename detail::unary_traits_imp<Operation*>::argument_type argument_type; 119 }; 120 121 template <class R, class A> 122 struct unary_traits<R(*)(A)> 123 { 124 typedef R (*function_type)(A); 125 typedef R (*param_type)(A); 126 typedef R result_type; 127 typedef A argument_type; 128 }; 129 130 template <class Operation> 131 struct binary_traits 132 { 133 typedef typename detail::binary_traits_imp<Operation*>::function_type function_type; 134 typedef typename detail::binary_traits_imp<Operation*>::param_type param_type; 135 typedef typename detail::binary_traits_imp<Operation*>::result_type result_type; 136 typedef typename detail::binary_traits_imp<Operation*>::first_argument_type first_argument_type; 137 typedef typename detail::binary_traits_imp<Operation*>::second_argument_type second_argument_type; 138 }; 139 140 template <class R, class A1, class A2> 141 struct binary_traits<R(*)(A1,A2)> 142 { 143 typedef R (*function_type)(A1,A2); 144 typedef R (*param_type)(A1,A2); 145 typedef R result_type; 146 typedef A1 first_argument_type; 147 typedef A2 second_argument_type; 148 }; 149 #else // BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION 150 // -------------------------------------------------------------------------- 151 // If we have no partial specialisation available, decay to a situation 152 // that is no worse than in the Standard, i.e., ptr_fun will be required. 153 // -------------------------------------------------------------------------- 154 155 template <class Operation> 156 struct unary_traits 157 { 158 typedef Operation function_type; 159 typedef const Operation& param_type; 160 typedef typename Operation::result_type result_type; 161 typedef typename Operation::argument_type argument_type; 162 }; 163 164 template <class Operation> 165 struct binary_traits 166 { 167 typedef Operation function_type; 168 typedef const Operation & param_type; 169 typedef typename Operation::result_type result_type; 170 typedef typename Operation::first_argument_type first_argument_type; 171 typedef typename Operation::second_argument_type second_argument_type; 172 }; 173 #endif // BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION 174 175 // -------------------------------------------------------------------------- 176 // unary_negate, not1 177 // -------------------------------------------------------------------------- 178 template <class Predicate> 179 class unary_negate 180 : public boost::functional::detail::unary_function<typename unary_traits<Predicate>::argument_type,bool> 181 { 182 public: unary_negate(typename unary_traits<Predicate>::param_type x)183 explicit unary_negate(typename unary_traits<Predicate>::param_type x) 184 : 185 pred(x) 186 {} operator ()(typename call_traits<typename unary_traits<Predicate>::argument_type>::param_type x) const187 bool operator()(typename call_traits<typename unary_traits<Predicate>::argument_type>::param_type x) const 188 { 189 return !pred(x); 190 } 191 private: 192 typename unary_traits<Predicate>::function_type pred; 193 }; 194 195 template <class Predicate> not1(const Predicate & pred)196 unary_negate<Predicate> not1(const Predicate &pred) 197 { 198 // The cast is to placate Borland C++Builder in certain circumstances. 199 // I don't think it should be necessary. 200 return unary_negate<Predicate>((typename unary_traits<Predicate>::param_type)pred); 201 } 202 203 template <class Predicate> not1(Predicate & pred)204 unary_negate<Predicate> not1(Predicate &pred) 205 { 206 return unary_negate<Predicate>(pred); 207 } 208 209 // -------------------------------------------------------------------------- 210 // binary_negate, not2 211 // -------------------------------------------------------------------------- 212 template <class Predicate> 213 class binary_negate 214 : public boost::functional::detail::binary_function< 215 typename binary_traits<Predicate>::first_argument_type, 216 typename binary_traits<Predicate>::second_argument_type, 217 bool> 218 { 219 public: binary_negate(typename binary_traits<Predicate>::param_type x)220 explicit binary_negate(typename binary_traits<Predicate>::param_type x) 221 : 222 pred(x) 223 {} operator ()(typename call_traits<typename binary_traits<Predicate>::first_argument_type>::param_type x,typename call_traits<typename binary_traits<Predicate>::second_argument_type>::param_type y) const224 bool operator()(typename call_traits<typename binary_traits<Predicate>::first_argument_type>::param_type x, 225 typename call_traits<typename binary_traits<Predicate>::second_argument_type>::param_type y) const 226 { 227 return !pred(x,y); 228 } 229 private: 230 typename binary_traits<Predicate>::function_type pred; 231 }; 232 233 template <class Predicate> not2(const Predicate & pred)234 binary_negate<Predicate> not2(const Predicate &pred) 235 { 236 // The cast is to placate Borland C++Builder in certain circumstances. 237 // I don't think it should be necessary. 238 return binary_negate<Predicate>((typename binary_traits<Predicate>::param_type)pred); 239 } 240 241 template <class Predicate> not2(Predicate & pred)242 binary_negate<Predicate> not2(Predicate &pred) 243 { 244 return binary_negate<Predicate>(pred); 245 } 246 247 // -------------------------------------------------------------------------- 248 // binder1st, bind1st 249 // -------------------------------------------------------------------------- 250 template <class Operation> 251 class binder1st 252 : public boost::functional::detail::unary_function< 253 typename binary_traits<Operation>::second_argument_type, 254 typename binary_traits<Operation>::result_type> 255 { 256 public: binder1st(typename binary_traits<Operation>::param_type x,typename call_traits<typename binary_traits<Operation>::first_argument_type>::param_type y)257 binder1st(typename binary_traits<Operation>::param_type x, 258 typename call_traits<typename binary_traits<Operation>::first_argument_type>::param_type y) 259 : 260 op(x), value(y) 261 {} 262 263 typename binary_traits<Operation>::result_type operator ()(typename call_traits<typename binary_traits<Operation>::second_argument_type>::param_type x) const264 operator()(typename call_traits<typename binary_traits<Operation>::second_argument_type>::param_type x) const 265 { 266 return op(value, x); 267 } 268 269 protected: 270 typename binary_traits<Operation>::function_type op; 271 typename binary_traits<Operation>::first_argument_type value; 272 }; 273 274 template <class Operation> bind1st(const Operation & op,typename call_traits<typename binary_traits<Operation>::first_argument_type>::param_type x)275 inline binder1st<Operation> bind1st(const Operation &op, 276 typename call_traits< 277 typename binary_traits<Operation>::first_argument_type 278 >::param_type x) 279 { 280 // The cast is to placate Borland C++Builder in certain circumstances. 281 // I don't think it should be necessary. 282 return binder1st<Operation>((typename binary_traits<Operation>::param_type)op, x); 283 } 284 285 template <class Operation> bind1st(Operation & op,typename call_traits<typename binary_traits<Operation>::first_argument_type>::param_type x)286 inline binder1st<Operation> bind1st(Operation &op, 287 typename call_traits< 288 typename binary_traits<Operation>::first_argument_type 289 >::param_type x) 290 { 291 return binder1st<Operation>(op, x); 292 } 293 294 // -------------------------------------------------------------------------- 295 // binder2nd, bind2nd 296 // -------------------------------------------------------------------------- 297 template <class Operation> 298 class binder2nd 299 : public boost::functional::detail::unary_function< 300 typename binary_traits<Operation>::first_argument_type, 301 typename binary_traits<Operation>::result_type> 302 { 303 public: binder2nd(typename binary_traits<Operation>::param_type x,typename call_traits<typename binary_traits<Operation>::second_argument_type>::param_type y)304 binder2nd(typename binary_traits<Operation>::param_type x, 305 typename call_traits<typename binary_traits<Operation>::second_argument_type>::param_type y) 306 : 307 op(x), value(y) 308 {} 309 310 typename binary_traits<Operation>::result_type operator ()(typename call_traits<typename binary_traits<Operation>::first_argument_type>::param_type x) const311 operator()(typename call_traits<typename binary_traits<Operation>::first_argument_type>::param_type x) const 312 { 313 return op(x, value); 314 } 315 316 protected: 317 typename binary_traits<Operation>::function_type op; 318 typename binary_traits<Operation>::second_argument_type value; 319 }; 320 321 template <class Operation> bind2nd(const Operation & op,typename call_traits<typename binary_traits<Operation>::second_argument_type>::param_type x)322 inline binder2nd<Operation> bind2nd(const Operation &op, 323 typename call_traits< 324 typename binary_traits<Operation>::second_argument_type 325 >::param_type x) 326 { 327 // The cast is to placate Borland C++Builder in certain circumstances. 328 // I don't think it should be necessary. 329 return binder2nd<Operation>((typename binary_traits<Operation>::param_type)op, x); 330 } 331 332 template <class Operation> bind2nd(Operation & op,typename call_traits<typename binary_traits<Operation>::second_argument_type>::param_type x)333 inline binder2nd<Operation> bind2nd(Operation &op, 334 typename call_traits< 335 typename binary_traits<Operation>::second_argument_type 336 >::param_type x) 337 { 338 return binder2nd<Operation>(op, x); 339 } 340 341 // -------------------------------------------------------------------------- 342 // mem_fun, etc 343 // -------------------------------------------------------------------------- 344 template <class S, class T> 345 class mem_fun_t : public boost::functional::detail::unary_function<T*, S> 346 { 347 public: mem_fun_t(S (T::* p)())348 explicit mem_fun_t(S (T::*p)()) 349 : 350 ptr(p) 351 {} operator ()(T * p) const352 S operator()(T* p) const 353 { 354 return (p->*ptr)(); 355 } 356 private: 357 S (T::*ptr)(); 358 }; 359 360 template <class S, class T, class A> 361 class mem_fun1_t : public boost::functional::detail::binary_function<T*, A, S> 362 { 363 public: mem_fun1_t(S (T::* p)(A))364 explicit mem_fun1_t(S (T::*p)(A)) 365 : 366 ptr(p) 367 {} operator ()(T * p,typename call_traits<A>::param_type x) const368 S operator()(T* p, typename call_traits<A>::param_type x) const 369 { 370 return (p->*ptr)(x); 371 } 372 private: 373 S (T::*ptr)(A); 374 }; 375 376 template <class S, class T> 377 class const_mem_fun_t : public boost::functional::detail::unary_function<const T*, S> 378 { 379 public: const_mem_fun_t(S (T::* p)()const)380 explicit const_mem_fun_t(S (T::*p)() const) 381 : 382 ptr(p) 383 {} operator ()(const T * p) const384 S operator()(const T* p) const 385 { 386 return (p->*ptr)(); 387 } 388 private: 389 S (T::*ptr)() const; 390 }; 391 392 template <class S, class T, class A> 393 class const_mem_fun1_t : public boost::functional::detail::binary_function<const T*, A, S> 394 { 395 public: const_mem_fun1_t(S (T::* p)(A)const)396 explicit const_mem_fun1_t(S (T::*p)(A) const) 397 : 398 ptr(p) 399 {} operator ()(const T * p,typename call_traits<A>::param_type x) const400 S operator()(const T* p, typename call_traits<A>::param_type x) const 401 { 402 return (p->*ptr)(x); 403 } 404 private: 405 S (T::*ptr)(A) const; 406 }; 407 408 template<class S, class T> mem_fun(S (T::* f)())409 inline mem_fun_t<S,T> mem_fun(S (T::*f)()) 410 { 411 return mem_fun_t<S,T>(f); 412 } 413 414 template<class S, class T, class A> mem_fun(S (T::* f)(A))415 inline mem_fun1_t<S,T,A> mem_fun(S (T::*f)(A)) 416 { 417 return mem_fun1_t<S,T,A>(f); 418 } 419 420 #ifndef BOOST_NO_POINTER_TO_MEMBER_CONST 421 template<class S, class T> mem_fun(S (T::* f)()const)422 inline const_mem_fun_t<S,T> mem_fun(S (T::*f)() const) 423 { 424 return const_mem_fun_t<S,T>(f); 425 } 426 427 template<class S, class T, class A> mem_fun(S (T::* f)(A)const)428 inline const_mem_fun1_t<S,T,A> mem_fun(S (T::*f)(A) const) 429 { 430 return const_mem_fun1_t<S,T,A>(f); 431 } 432 #endif // BOOST_NO_POINTER_TO_MEMBER_CONST 433 434 // -------------------------------------------------------------------------- 435 // mem_fun_ref, etc 436 // -------------------------------------------------------------------------- 437 template <class S, class T> 438 class mem_fun_ref_t : public boost::functional::detail::unary_function<T&, S> 439 { 440 public: mem_fun_ref_t(S (T::* p)())441 explicit mem_fun_ref_t(S (T::*p)()) 442 : 443 ptr(p) 444 {} operator ()(T & p) const445 S operator()(T& p) const 446 { 447 return (p.*ptr)(); 448 } 449 private: 450 S (T::*ptr)(); 451 }; 452 453 template <class S, class T, class A> 454 class mem_fun1_ref_t : public boost::functional::detail::binary_function<T&, A, S> 455 { 456 public: mem_fun1_ref_t(S (T::* p)(A))457 explicit mem_fun1_ref_t(S (T::*p)(A)) 458 : 459 ptr(p) 460 {} operator ()(T & p,typename call_traits<A>::param_type x) const461 S operator()(T& p, typename call_traits<A>::param_type x) const 462 { 463 return (p.*ptr)(x); 464 } 465 private: 466 S (T::*ptr)(A); 467 }; 468 469 template <class S, class T> 470 class const_mem_fun_ref_t : public boost::functional::detail::unary_function<const T&, S> 471 { 472 public: const_mem_fun_ref_t(S (T::* p)()const)473 explicit const_mem_fun_ref_t(S (T::*p)() const) 474 : 475 ptr(p) 476 {} 477 operator ()(const T & p) const478 S operator()(const T &p) const 479 { 480 return (p.*ptr)(); 481 } 482 private: 483 S (T::*ptr)() const; 484 }; 485 486 template <class S, class T, class A> 487 class const_mem_fun1_ref_t : public boost::functional::detail::binary_function<const T&, A, S> 488 { 489 public: const_mem_fun1_ref_t(S (T::* p)(A)const)490 explicit const_mem_fun1_ref_t(S (T::*p)(A) const) 491 : 492 ptr(p) 493 {} 494 operator ()(const T & p,typename call_traits<A>::param_type x) const495 S operator()(const T& p, typename call_traits<A>::param_type x) const 496 { 497 return (p.*ptr)(x); 498 } 499 private: 500 S (T::*ptr)(A) const; 501 }; 502 503 template<class S, class T> mem_fun_ref(S (T::* f)())504 inline mem_fun_ref_t<S,T> mem_fun_ref(S (T::*f)()) 505 { 506 return mem_fun_ref_t<S,T>(f); 507 } 508 509 template<class S, class T, class A> mem_fun_ref(S (T::* f)(A))510 inline mem_fun1_ref_t<S,T,A> mem_fun_ref(S (T::*f)(A)) 511 { 512 return mem_fun1_ref_t<S,T,A>(f); 513 } 514 515 #ifndef BOOST_NO_POINTER_TO_MEMBER_CONST 516 template<class S, class T> mem_fun_ref(S (T::* f)()const)517 inline const_mem_fun_ref_t<S,T> mem_fun_ref(S (T::*f)() const) 518 { 519 return const_mem_fun_ref_t<S,T>(f); 520 } 521 522 template<class S, class T, class A> mem_fun_ref(S (T::* f)(A)const)523 inline const_mem_fun1_ref_t<S,T,A> mem_fun_ref(S (T::*f)(A) const) 524 { 525 return const_mem_fun1_ref_t<S,T,A>(f); 526 } 527 #endif // BOOST_NO_POINTER_TO_MEMBER_CONST 528 529 // -------------------------------------------------------------------------- 530 // ptr_fun 531 // -------------------------------------------------------------------------- 532 template <class Arg, class Result> 533 class pointer_to_unary_function : public boost::functional::detail::unary_function<Arg,Result> 534 { 535 public: pointer_to_unary_function(Result (* f)(Arg))536 explicit pointer_to_unary_function(Result (*f)(Arg)) 537 : 538 func(f) 539 {} 540 operator ()(typename call_traits<Arg>::param_type x) const541 Result operator()(typename call_traits<Arg>::param_type x) const 542 { 543 return func(x); 544 } 545 546 private: 547 Result (*func)(Arg); 548 }; 549 550 template <class Arg, class Result> ptr_fun(Result (* f)(Arg))551 inline pointer_to_unary_function<Arg,Result> ptr_fun(Result (*f)(Arg)) 552 { 553 return pointer_to_unary_function<Arg,Result>(f); 554 } 555 556 template <class Arg1, class Arg2, class Result> 557 class pointer_to_binary_function : public boost::functional::detail::binary_function<Arg1,Arg2,Result> 558 { 559 public: pointer_to_binary_function(Result (* f)(Arg1,Arg2))560 explicit pointer_to_binary_function(Result (*f)(Arg1, Arg2)) 561 : 562 func(f) 563 {} 564 operator ()(typename call_traits<Arg1>::param_type x,typename call_traits<Arg2>::param_type y) const565 Result operator()(typename call_traits<Arg1>::param_type x, typename call_traits<Arg2>::param_type y) const 566 { 567 return func(x,y); 568 } 569 570 private: 571 Result (*func)(Arg1, Arg2); 572 }; 573 574 template <class Arg1, class Arg2, class Result> ptr_fun(Result (* f)(Arg1,Arg2))575 inline pointer_to_binary_function<Arg1,Arg2,Result> ptr_fun(Result (*f)(Arg1, Arg2)) 576 { 577 return pointer_to_binary_function<Arg1,Arg2,Result>(f); 578 } 579 } // namespace boost 580 581 #endif 582