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 // ------------------------------------------------------------------------------
10 // ------------------------------------------------------------------------------
12 #ifndef BOOST_FUNCTIONAL_HPP
13 #define BOOST_FUNCTIONAL_HPP
15 #include <boost/config.hpp>
16 #include <boost/call_traits.hpp>
24 #if defined(_HAS_AUTO_PTR_ETC) && !_HAS_AUTO_PTR_ETC
25 // std::unary_function and std::binary_function were both removed
28 template <typename Arg1, typename Result>
31 typedef Arg1 argument_type;
32 typedef Result result_type;
35 template <typename Arg1, typename Arg2, typename Result>
36 struct binary_function
38 typedef Arg1 first_argument_type;
39 typedef Arg2 second_argument_type;
40 typedef Result result_type;
43 // Use the standard objects when we have them.
45 using std::unary_function;
46 using std::binary_function;
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
57 // In addition to the standard types defined in unary_function and
58 // binary_function, we add
60 // - function_type, the type of the function or function object itself.
62 // - param_type, the type that should be used for passing the function or
63 // function object as an argument.
64 // --------------------------------------------------------------------------
67 template <class Operation>
68 struct unary_traits_imp;
70 template <class Operation>
71 struct unary_traits_imp<Operation*>
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;
79 template <class R, class A>
80 struct unary_traits_imp<R(*)(A)>
82 typedef R (*function_type)(A);
83 typedef R (*param_type)(A);
84 typedef R result_type;
85 typedef A argument_type;
88 template <class Operation>
89 struct binary_traits_imp;
91 template <class Operation>
92 struct binary_traits_imp<Operation*>
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;
101 template <class R, class A1, class A2>
102 struct binary_traits_imp<R(*)(A1,A2)>
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;
110 } // namespace detail
112 template <class Operation>
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;
121 template <class R, class A>
122 struct unary_traits<R(*)(A)>
124 typedef R (*function_type)(A);
125 typedef R (*param_type)(A);
126 typedef R result_type;
127 typedef A argument_type;
130 template <class Operation>
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;
140 template <class R, class A1, class A2>
141 struct binary_traits<R(*)(A1,A2)>
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;
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 // --------------------------------------------------------------------------
155 template <class Operation>
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;
164 template <class Operation>
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;
173 #endif // BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
175 // --------------------------------------------------------------------------
176 // unary_negate, not1
177 // --------------------------------------------------------------------------
178 template <class Predicate>
180 : public boost::functional::detail::unary_function<typename unary_traits<Predicate>::argument_type,bool>
183 explicit unary_negate(typename unary_traits<Predicate>::param_type x)
187 bool operator()(typename call_traits<typename unary_traits<Predicate>::argument_type>::param_type x) const
192 typename unary_traits<Predicate>::function_type pred;
195 template <class Predicate>
196 unary_negate<Predicate> not1(const Predicate &pred)
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);
203 template <class Predicate>
204 unary_negate<Predicate> not1(Predicate &pred)
206 return unary_negate<Predicate>(pred);
209 // --------------------------------------------------------------------------
210 // binary_negate, not2
211 // --------------------------------------------------------------------------
212 template <class Predicate>
214 : public boost::functional::detail::binary_function<
215 typename binary_traits<Predicate>::first_argument_type,
216 typename binary_traits<Predicate>::second_argument_type,
220 explicit binary_negate(typename binary_traits<Predicate>::param_type x)
224 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
230 typename binary_traits<Predicate>::function_type pred;
233 template <class Predicate>
234 binary_negate<Predicate> not2(const Predicate &pred)
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);
241 template <class Predicate>
242 binary_negate<Predicate> not2(Predicate &pred)
244 return binary_negate<Predicate>(pred);
247 // --------------------------------------------------------------------------
248 // binder1st, bind1st
249 // --------------------------------------------------------------------------
250 template <class Operation>
252 : public boost::functional::detail::unary_function<
253 typename binary_traits<Operation>::second_argument_type,
254 typename binary_traits<Operation>::result_type>
257 binder1st(typename binary_traits<Operation>::param_type x,
258 typename call_traits<typename binary_traits<Operation>::first_argument_type>::param_type y)
263 typename binary_traits<Operation>::result_type
264 operator()(typename call_traits<typename binary_traits<Operation>::second_argument_type>::param_type x) const
270 typename binary_traits<Operation>::function_type op;
271 typename binary_traits<Operation>::first_argument_type value;
274 template <class Operation>
275 inline binder1st<Operation> bind1st(const Operation &op,
276 typename call_traits<
277 typename binary_traits<Operation>::first_argument_type
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);
285 template <class Operation>
286 inline binder1st<Operation> bind1st(Operation &op,
287 typename call_traits<
288 typename binary_traits<Operation>::first_argument_type
291 return binder1st<Operation>(op, x);
294 // --------------------------------------------------------------------------
295 // binder2nd, bind2nd
296 // --------------------------------------------------------------------------
297 template <class Operation>
299 : public boost::functional::detail::unary_function<
300 typename binary_traits<Operation>::first_argument_type,
301 typename binary_traits<Operation>::result_type>
304 binder2nd(typename binary_traits<Operation>::param_type x,
305 typename call_traits<typename binary_traits<Operation>::second_argument_type>::param_type y)
310 typename binary_traits<Operation>::result_type
311 operator()(typename call_traits<typename binary_traits<Operation>::first_argument_type>::param_type x) const
317 typename binary_traits<Operation>::function_type op;
318 typename binary_traits<Operation>::second_argument_type value;
321 template <class Operation>
322 inline binder2nd<Operation> bind2nd(const Operation &op,
323 typename call_traits<
324 typename binary_traits<Operation>::second_argument_type
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);
332 template <class Operation>
333 inline binder2nd<Operation> bind2nd(Operation &op,
334 typename call_traits<
335 typename binary_traits<Operation>::second_argument_type
338 return binder2nd<Operation>(op, x);
341 // --------------------------------------------------------------------------
343 // --------------------------------------------------------------------------
344 template <class S, class T>
345 class mem_fun_t : public boost::functional::detail::unary_function<T*, S>
348 explicit mem_fun_t(S (T::*p)())
352 S operator()(T* p) const
360 template <class S, class T, class A>
361 class mem_fun1_t : public boost::functional::detail::binary_function<T*, A, S>
364 explicit mem_fun1_t(S (T::*p)(A))
368 S operator()(T* p, typename call_traits<A>::param_type x) const
376 template <class S, class T>
377 class const_mem_fun_t : public boost::functional::detail::unary_function<const T*, S>
380 explicit const_mem_fun_t(S (T::*p)() const)
384 S operator()(const T* p) const
392 template <class S, class T, class A>
393 class const_mem_fun1_t : public boost::functional::detail::binary_function<const T*, A, S>
396 explicit const_mem_fun1_t(S (T::*p)(A) const)
400 S operator()(const T* p, typename call_traits<A>::param_type x) const
405 S (T::*ptr)(A) const;
408 template<class S, class T>
409 inline mem_fun_t<S,T> mem_fun(S (T::*f)())
411 return mem_fun_t<S,T>(f);
414 template<class S, class T, class A>
415 inline mem_fun1_t<S,T,A> mem_fun(S (T::*f)(A))
417 return mem_fun1_t<S,T,A>(f);
420 #ifndef BOOST_NO_POINTER_TO_MEMBER_CONST
421 template<class S, class T>
422 inline const_mem_fun_t<S,T> mem_fun(S (T::*f)() const)
424 return const_mem_fun_t<S,T>(f);
427 template<class S, class T, class A>
428 inline const_mem_fun1_t<S,T,A> mem_fun(S (T::*f)(A) const)
430 return const_mem_fun1_t<S,T,A>(f);
432 #endif // BOOST_NO_POINTER_TO_MEMBER_CONST
434 // --------------------------------------------------------------------------
436 // --------------------------------------------------------------------------
437 template <class S, class T>
438 class mem_fun_ref_t : public boost::functional::detail::unary_function<T&, S>
441 explicit mem_fun_ref_t(S (T::*p)())
445 S operator()(T& p) const
453 template <class S, class T, class A>
454 class mem_fun1_ref_t : public boost::functional::detail::binary_function<T&, A, S>
457 explicit mem_fun1_ref_t(S (T::*p)(A))
461 S operator()(T& p, typename call_traits<A>::param_type x) const
469 template <class S, class T>
470 class const_mem_fun_ref_t : public boost::functional::detail::unary_function<const T&, S>
473 explicit const_mem_fun_ref_t(S (T::*p)() const)
478 S operator()(const T &p) const
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>
490 explicit const_mem_fun1_ref_t(S (T::*p)(A) const)
495 S operator()(const T& p, typename call_traits<A>::param_type x) const
500 S (T::*ptr)(A) const;
503 template<class S, class T>
504 inline mem_fun_ref_t<S,T> mem_fun_ref(S (T::*f)())
506 return mem_fun_ref_t<S,T>(f);
509 template<class S, class T, class A>
510 inline mem_fun1_ref_t<S,T,A> mem_fun_ref(S (T::*f)(A))
512 return mem_fun1_ref_t<S,T,A>(f);
515 #ifndef BOOST_NO_POINTER_TO_MEMBER_CONST
516 template<class S, class T>
517 inline const_mem_fun_ref_t<S,T> mem_fun_ref(S (T::*f)() const)
519 return const_mem_fun_ref_t<S,T>(f);
522 template<class S, class T, class A>
523 inline const_mem_fun1_ref_t<S,T,A> mem_fun_ref(S (T::*f)(A) const)
525 return const_mem_fun1_ref_t<S,T,A>(f);
527 #endif // BOOST_NO_POINTER_TO_MEMBER_CONST
529 // --------------------------------------------------------------------------
531 // --------------------------------------------------------------------------
532 template <class Arg, class Result>
533 class pointer_to_unary_function : public boost::functional::detail::unary_function<Arg,Result>
536 explicit pointer_to_unary_function(Result (*f)(Arg))
541 Result operator()(typename call_traits<Arg>::param_type x) const
550 template <class Arg, class Result>
551 inline pointer_to_unary_function<Arg,Result> ptr_fun(Result (*f)(Arg))
553 return pointer_to_unary_function<Arg,Result>(f);
556 template <class Arg1, class Arg2, class Result>
557 class pointer_to_binary_function : public boost::functional::detail::binary_function<Arg1,Arg2,Result>
560 explicit pointer_to_binary_function(Result (*f)(Arg1, Arg2))
565 Result operator()(typename call_traits<Arg1>::param_type x, typename call_traits<Arg2>::param_type y) const
571 Result (*func)(Arg1, Arg2);
574 template <class Arg1, class Arg2, class Result>
575 inline pointer_to_binary_function<Arg1,Arg2,Result> ptr_fun(Result (*f)(Arg1, Arg2))
577 return pointer_to_binary_function<Arg1,Arg2,Result>(f);