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