Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: downloads/boost_1_34_1/boost/functional.hpp @ 47

Last change on this file since 47 was 29, checked in by landauf, 16 years ago

updated boost from 1_33_1 to 1_34_1

File size: 18.5 KB
Line 
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: functional.hpp,v 1.4.20.1 2006/12/02 14:17:26 andreas_huber69 Exp $
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
19namespace 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:
153        explicit unary_negate(typename unary_traits<Predicate>::param_type x)
154            :
155            pred(x)
156        {}
157        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>
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>
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:
189        explicit binary_negate(typename binary_traits<Predicate>::param_type x)
190            :
191            pred(x)
192        {}
193        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>
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>
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:
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
232        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>
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>
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:
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
278        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>
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>
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:
315        explicit mem_fun_t(S (T::*p)())
316            :
317            ptr(p)
318        {}
319        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:   
331        explicit mem_fun1_t(S (T::*p)(A))
332            :
333            ptr(p)
334        {}
335        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:
347        explicit const_mem_fun_t(S (T::*p)() const)
348            :
349            ptr(p)
350        {}
351        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:
363        explicit const_mem_fun1_t(S (T::*p)(A) const)
364            :
365            ptr(p)
366        {}
367        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>
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>
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>
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>
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:
408        explicit mem_fun_ref_t(S (T::*p)())
409            :
410            ptr(p)
411        {}
412        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:
424        explicit mem_fun1_ref_t(S (T::*p)(A))
425            :
426            ptr(p)
427        {}
428        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:
440        explicit const_mem_fun_ref_t(S (T::*p)() const)
441            :
442            ptr(p)
443        {}
444       
445        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:
457        explicit const_mem_fun1_ref_t(S (T::*p)(A) const)
458            :
459            ptr(p)
460        {}
461
462        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>
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>
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>
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>
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:
503        explicit pointer_to_unary_function(Result (*f)(Arg))
504            :
505            func(f)
506        {}
507
508        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>
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:
527        explicit pointer_to_binary_function(Result (*f)(Arg1, Arg2))
528            :
529            func(f)
530        {}
531       
532        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>
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
Note: See TracBrowser for help on using the repository browser.