1 // ------------------------------------------------------------------------------
2 // Boost functional.hpp header file
3 // See http://www.boost.org/libs/functional for documentation.
4 // ------------------------------------------------------------------------------
6 // Cadenza New Zealand Ltd
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
16 // ------------------------------------------------------------------------------
17 // $Id: functional.hpp,v 1.4 2002/12/27 16:51:52 beman_dawes Exp $
18 // ------------------------------------------------------------------------------
20 #ifndef BOOST_FUNCTIONAL_HPP
21 #define BOOST_FUNCTIONAL_HPP
23 #include <boost/config.hpp>
24 #include <boost/call_traits.hpp>
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
35 // In addition to the standard types defined in unary_function and
36 // binary_function, we add
38 // - function_type, the type of the function or function object itself.
40 // - param_type, the type that should be used for passing the function or
41 // function object as an argument.
42 // --------------------------------------------------------------------------
45 template <class Operation>
46 struct unary_traits_imp;
48 template <class Operation>
49 struct unary_traits_imp<Operation*>
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;
57 template <class R, class A>
58 struct unary_traits_imp<R(*)(A)>
60 typedef R (*function_type)(A);
61 typedef R (*param_type)(A);
62 typedef R result_type;
63 typedef A argument_type;
66 template <class Operation>
67 struct binary_traits_imp;
69 template <class Operation>
70 struct binary_traits_imp<Operation*>
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;
79 template <class R, class A1, class A2>
80 struct binary_traits_imp<R(*)(A1,A2)>
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;
90 template <class Operation>
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;
99 template <class R, class A>
100 struct unary_traits<R(*)(A)>
102 typedef R (*function_type)(A);
103 typedef R (*param_type)(A);
104 typedef R result_type;
105 typedef A argument_type;
108 template <class Operation>
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;
118 template <class R, class A1, class A2>
119 struct binary_traits<R(*)(A1,A2)>
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;
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 // --------------------------------------------------------------------------
133 template <class Operation>
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;
142 template <class Operation>
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;
151 #endif // BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
153 // --------------------------------------------------------------------------
154 // unary_negate, not1
155 // --------------------------------------------------------------------------
156 template <class Predicate>
158 : public std::unary_function<typename unary_traits<Predicate>::argument_type,bool>
161 explicit unary_negate(typename unary_traits<Predicate>::param_type x)
165 bool operator()(typename call_traits<typename unary_traits<Predicate>::argument_type>::param_type x) const
170 typename unary_traits<Predicate>::function_type pred;
173 template <class Predicate>
174 unary_negate<Predicate> not1(const Predicate &pred)
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);
181 template <class Predicate>
182 unary_negate<Predicate> not1(Predicate &pred)
184 return unary_negate<Predicate>(pred);
187 // --------------------------------------------------------------------------
188 // binary_negate, not2
189 // --------------------------------------------------------------------------
190 template <class Predicate>
192 : public std::binary_function<typename binary_traits<Predicate>::first_argument_type,
193 typename binary_traits<Predicate>::second_argument_type,
197 explicit binary_negate(typename binary_traits<Predicate>::param_type x)
201 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
207 typename binary_traits<Predicate>::function_type pred;
210 template <class Predicate>
211 binary_negate<Predicate> not2(const Predicate &pred)
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);
218 template <class Predicate>
219 binary_negate<Predicate> not2(Predicate &pred)
221 return binary_negate<Predicate>(pred);
224 // --------------------------------------------------------------------------
225 // binder1st, bind1st
226 // --------------------------------------------------------------------------
227 template <class Operation>
229 : public std::unary_function<typename binary_traits<Operation>::second_argument_type,
230 typename binary_traits<Operation>::result_type>
233 binder1st(typename binary_traits<Operation>::param_type x,
234 typename call_traits<typename binary_traits<Operation>::first_argument_type>::param_type y)
239 typename binary_traits<Operation>::result_type
240 operator()(typename call_traits<typename binary_traits<Operation>::second_argument_type>::param_type x) const
246 typename binary_traits<Operation>::function_type op;
247 typename binary_traits<Operation>::first_argument_type value;
250 template <class Operation>
251 inline binder1st<Operation> bind1st(const Operation &op,
252 typename call_traits<
253 typename binary_traits<Operation>::first_argument_type
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);
261 template <class Operation>
262 inline binder1st<Operation> bind1st(Operation &op,
263 typename call_traits<
264 typename binary_traits<Operation>::first_argument_type
267 return binder1st<Operation>(op, x);
270 // --------------------------------------------------------------------------
271 // binder2nd, bind2nd
272 // --------------------------------------------------------------------------
273 template <class Operation>
275 : public std::unary_function<typename binary_traits<Operation>::first_argument_type,
276 typename binary_traits<Operation>::result_type>
279 binder2nd(typename binary_traits<Operation>::param_type x,
280 typename call_traits<typename binary_traits<Operation>::second_argument_type>::param_type y)
285 typename binary_traits<Operation>::result_type
286 operator()(typename call_traits<typename binary_traits<Operation>::first_argument_type>::param_type x) const
292 typename binary_traits<Operation>::function_type op;
293 typename binary_traits<Operation>::second_argument_type value;
296 template <class Operation>
297 inline binder2nd<Operation> bind2nd(const Operation &op,
298 typename call_traits<
299 typename binary_traits<Operation>::second_argument_type
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);
307 template <class Operation>
308 inline binder2nd<Operation> bind2nd(Operation &op,
309 typename call_traits<
310 typename binary_traits<Operation>::second_argument_type
313 return binder2nd<Operation>(op, x);
316 // --------------------------------------------------------------------------
318 // --------------------------------------------------------------------------
319 template <class S, class T>
320 class mem_fun_t : public std::unary_function<T*, S>
323 explicit mem_fun_t(S (T::*p)())
327 S operator()(T* p) const
335 template <class S, class T, class A>
336 class mem_fun1_t : public std::binary_function<T*, A, S>
339 explicit mem_fun1_t(S (T::*p)(A))
343 S operator()(T* p, typename call_traits<A>::param_type x) const
351 template <class S, class T>
352 class const_mem_fun_t : public std::unary_function<const T*, S>
355 explicit const_mem_fun_t(S (T::*p)() const)
359 S operator()(const T* p) const
367 template <class S, class T, class A>
368 class const_mem_fun1_t : public std::binary_function<const T*, A, S>
371 explicit const_mem_fun1_t(S (T::*p)(A) const)
375 S operator()(const T* p, typename call_traits<A>::param_type x) const
380 S (T::*ptr)(A) const;
383 template<class S, class T>
384 inline mem_fun_t<S,T> mem_fun(S (T::*f)())
386 return mem_fun_t<S,T>(f);
389 template<class S, class T, class A>
390 inline mem_fun1_t<S,T,A> mem_fun(S (T::*f)(A))
392 return mem_fun1_t<S,T,A>(f);
395 #ifndef BOOST_NO_POINTER_TO_MEMBER_CONST
396 template<class S, class T>
397 inline const_mem_fun_t<S,T> mem_fun(S (T::*f)() const)
399 return const_mem_fun_t<S,T>(f);
402 template<class S, class T, class A>
403 inline const_mem_fun1_t<S,T,A> mem_fun(S (T::*f)(A) const)
405 return const_mem_fun1_t<S,T,A>(f);
407 #endif // BOOST_NO_POINTER_TO_MEMBER_CONST
409 // --------------------------------------------------------------------------
411 // --------------------------------------------------------------------------
412 template <class S, class T>
413 class mem_fun_ref_t : public std::unary_function<T&, S>
416 explicit mem_fun_ref_t(S (T::*p)())
420 S operator()(T& p) const
428 template <class S, class T, class A>
429 class mem_fun1_ref_t : public std::binary_function<T&, A, S>
432 explicit mem_fun1_ref_t(S (T::*p)(A))
436 S operator()(T& p, typename call_traits<A>::param_type x) const
444 template <class S, class T>
445 class const_mem_fun_ref_t : public std::unary_function<const T&, S>
448 explicit const_mem_fun_ref_t(S (T::*p)() const)
453 S operator()(const T &p) const
461 template <class S, class T, class A>
462 class const_mem_fun1_ref_t : public std::binary_function<const T&, A, S>
465 explicit const_mem_fun1_ref_t(S (T::*p)(A) const)
470 S operator()(const T& p, typename call_traits<A>::param_type x) const
475 S (T::*ptr)(A) const;
478 template<class S, class T>
479 inline mem_fun_ref_t<S,T> mem_fun_ref(S (T::*f)())
481 return mem_fun_ref_t<S,T>(f);
484 template<class S, class T, class A>
485 inline mem_fun1_ref_t<S,T,A> mem_fun_ref(S (T::*f)(A))
487 return mem_fun1_ref_t<S,T,A>(f);
490 #ifndef BOOST_NO_POINTER_TO_MEMBER_CONST
491 template<class S, class T>
492 inline const_mem_fun_ref_t<S,T> mem_fun_ref(S (T::*f)() const)
494 return const_mem_fun_ref_t<S,T>(f);
497 template<class S, class T, class A>
498 inline const_mem_fun1_ref_t<S,T,A> mem_fun_ref(S (T::*f)(A) const)
500 return const_mem_fun1_ref_t<S,T,A>(f);
502 #endif // BOOST_NO_POINTER_TO_MEMBER_CONST
504 // --------------------------------------------------------------------------
506 // --------------------------------------------------------------------------
507 template <class Arg, class Result>
508 class pointer_to_unary_function : public std::unary_function<Arg,Result>
511 explicit pointer_to_unary_function(Result (*f)(Arg))
516 Result operator()(typename call_traits<Arg>::param_type x) const
525 template <class Arg, class Result>
526 inline pointer_to_unary_function<Arg,Result> ptr_fun(Result (*f)(Arg))
528 return pointer_to_unary_function<Arg,Result>(f);
531 template <class Arg1, class Arg2, class Result>
532 class pointer_to_binary_function : public std::binary_function<Arg1,Arg2,Result>
535 explicit pointer_to_binary_function(Result (*f)(Arg1, Arg2))
540 Result operator()(typename call_traits<Arg1>::param_type x, typename call_traits<Arg2>::param_type y) const
546 Result (*func)(Arg1, Arg2);
549 template <class Arg1, class Arg2, class Result>
550 inline pointer_to_binary_function<Arg1,Arg2,Result> ptr_fun(Result (*f)(Arg1, Arg2))
552 return pointer_to_binary_function<Arg1,Arg2,Result>(f);