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