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