source: NonGTP/Boost/boost/functional.hpp @ 857

Revision 857, 19.3 KB checked in by igarcia, 19 years ago (diff)
Line 
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.4 2002/12/27 16:51:52 beman_dawes 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
27namespace 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:
161        explicit unary_negate(typename unary_traits<Predicate>::param_type x)
162            :
163            pred(x)
164        {}
165        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>
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>
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:
197        explicit binary_negate(typename binary_traits<Predicate>::param_type x)
198            :
199            pred(x)
200        {}
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
203        {
204            return !pred(x,y);
205        }
206      private:
207        typename binary_traits<Predicate>::function_type pred;
208    };
209
210    template <class Predicate>
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>
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:
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
240        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>
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>
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:
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
286        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>
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>
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:
323        explicit mem_fun_t(S (T::*p)())
324            :
325            ptr(p)
326        {}
327        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:   
339        explicit mem_fun1_t(S (T::*p)(A))
340            :
341            ptr(p)
342        {}
343        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:
355        explicit const_mem_fun_t(S (T::*p)() const)
356            :
357            ptr(p)
358        {}
359        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:
371        explicit const_mem_fun1_t(S (T::*p)(A) const)
372            :
373            ptr(p)
374        {}
375        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>
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>
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>
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>
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:
416        explicit mem_fun_ref_t(S (T::*p)())
417            :
418            ptr(p)
419        {}
420        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:
432        explicit mem_fun1_ref_t(S (T::*p)(A))
433            :
434            ptr(p)
435        {}
436        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:
448        explicit const_mem_fun_ref_t(S (T::*p)() const)
449            :
450            ptr(p)
451        {}
452       
453        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:
465        explicit const_mem_fun1_ref_t(S (T::*p)(A) const)
466            :
467            ptr(p)
468        {}
469
470        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>
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>
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>
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>
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:
511        explicit pointer_to_unary_function(Result (*f)(Arg))
512            :
513            func(f)
514        {}
515
516        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>
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:
535        explicit pointer_to_binary_function(Result (*f)(Arg1, Arg2))
536            :
537            func(f)
538        {}
539       
540        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>
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
Note: See TracBrowser for help on using the repository browser.