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