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     namespace functional
22     {
23         namespace detail {
24 #if defined(_HAS_AUTO_PTR_ETC) && !_HAS_AUTO_PTR_ETC
25             // std::unary_function and std::binary_function were both removed
26             // in C++17.
27 
28             template <typename Arg1, typename Result>
29             struct unary_function
30             {
31                 typedef Arg1 argument_type;
32                 typedef Result result_type;
33             };
34 
35             template <typename Arg1, typename Arg2, typename Result>
36             struct binary_function
37             {
38                 typedef Arg1 first_argument_type;
39                 typedef Arg2 second_argument_type;
40                 typedef Result result_type;
41             };
42 #else
43             // Use the standard objects when we have them.
44 
45             using std::unary_function;
46             using std::binary_function;
47 #endif
48         }
49     }
50 
51 #ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
52     // --------------------------------------------------------------------------
53     // The following traits classes allow us to avoid the need for ptr_fun
54     // because the types of arguments and the result of a function can be
55     // deduced.
56     //
57     // In addition to the standard types defined in unary_function and
58     // binary_function, we add
59     //
60     // - function_type, the type of the function or function object itself.
61     //
62     // - param_type, the type that should be used for passing the function or
63     //   function object as an argument.
64     // --------------------------------------------------------------------------
65     namespace detail
66     {
67         template <class Operation>
68         struct unary_traits_imp;
69 
70         template <class Operation>
71         struct unary_traits_imp<Operation*>
72         {
73             typedef Operation                         function_type;
74             typedef const function_type &             param_type;
75             typedef typename Operation::result_type   result_type;
76             typedef typename Operation::argument_type argument_type;
77         };
78 
79         template <class R, class A>
80         struct unary_traits_imp<R(*)(A)>
81         {
82             typedef R (*function_type)(A);
83             typedef R (*param_type)(A);
84             typedef R result_type;
85             typedef A argument_type;
86         };
87 
88         template <class Operation>
89         struct binary_traits_imp;
90 
91         template <class Operation>
92         struct binary_traits_imp<Operation*>
93         {
94             typedef Operation                                function_type;
95             typedef const function_type &                    param_type;
96             typedef typename Operation::result_type          result_type;
97             typedef typename Operation::first_argument_type  first_argument_type;
98             typedef typename Operation::second_argument_type second_argument_type;
99         };
100 
101         template <class R, class A1, class A2>
102         struct binary_traits_imp<R(*)(A1,A2)>
103         {
104             typedef R (*function_type)(A1,A2);
105             typedef R (*param_type)(A1,A2);
106             typedef R result_type;
107             typedef A1 first_argument_type;
108             typedef A2 second_argument_type;
109         };
110     } // namespace detail
111 
112     template <class Operation>
113     struct unary_traits
114     {
115         typedef typename detail::unary_traits_imp<Operation*>::function_type function_type;
116         typedef typename detail::unary_traits_imp<Operation*>::param_type    param_type;
117         typedef typename detail::unary_traits_imp<Operation*>::result_type   result_type;
118         typedef typename detail::unary_traits_imp<Operation*>::argument_type argument_type;
119     };
120 
121     template <class R, class A>
122     struct unary_traits<R(*)(A)>
123     {
124         typedef R (*function_type)(A);
125         typedef R (*param_type)(A);
126         typedef R result_type;
127         typedef A argument_type;
128     };
129 
130     template <class Operation>
131     struct binary_traits
132     {
133         typedef typename detail::binary_traits_imp<Operation*>::function_type        function_type;
134         typedef typename detail::binary_traits_imp<Operation*>::param_type           param_type;
135         typedef typename detail::binary_traits_imp<Operation*>::result_type          result_type;
136         typedef typename detail::binary_traits_imp<Operation*>::first_argument_type  first_argument_type;
137         typedef typename detail::binary_traits_imp<Operation*>::second_argument_type second_argument_type;
138     };
139 
140     template <class R, class A1, class A2>
141     struct binary_traits<R(*)(A1,A2)>
142     {
143         typedef R (*function_type)(A1,A2);
144         typedef R (*param_type)(A1,A2);
145         typedef R result_type;
146         typedef A1 first_argument_type;
147         typedef A2 second_argument_type;
148     };
149 #else // BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
150     // --------------------------------------------------------------------------
151     // If we have no partial specialisation available, decay to a situation
152     // that is no worse than in the Standard, i.e., ptr_fun will be required.
153     // --------------------------------------------------------------------------
154 
155     template <class Operation>
156     struct unary_traits
157     {
158         typedef Operation                         function_type;
159         typedef const Operation&                  param_type;
160         typedef typename Operation::result_type   result_type;
161         typedef typename Operation::argument_type argument_type;
162     };
163 
164     template <class Operation>
165     struct binary_traits
166     {
167         typedef Operation                                function_type;
168         typedef const Operation &                        param_type;
169         typedef typename Operation::result_type          result_type;
170         typedef typename Operation::first_argument_type  first_argument_type;
171         typedef typename Operation::second_argument_type second_argument_type;
172     };
173 #endif // BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
174 
175     // --------------------------------------------------------------------------
176     // unary_negate, not1
177     // --------------------------------------------------------------------------
178     template <class Predicate>
179     class unary_negate
180         : public boost::functional::detail::unary_function<typename unary_traits<Predicate>::argument_type,bool>
181     {
182       public:
unary_negate(typename unary_traits<Predicate>::param_type x)183         explicit unary_negate(typename unary_traits<Predicate>::param_type x)
184             :
185             pred(x)
186         {}
operator ()(typename call_traits<typename unary_traits<Predicate>::argument_type>::param_type x) const187         bool operator()(typename call_traits<typename unary_traits<Predicate>::argument_type>::param_type x) const
188         {
189             return !pred(x);
190         }
191       private:
192         typename unary_traits<Predicate>::function_type pred;
193     };
194 
195     template <class Predicate>
not1(const Predicate & pred)196     unary_negate<Predicate> not1(const Predicate &pred)
197     {
198         // The cast is to placate Borland C++Builder in certain circumstances.
199         // I don't think it should be necessary.
200         return unary_negate<Predicate>((typename unary_traits<Predicate>::param_type)pred);
201     }
202 
203     template <class Predicate>
not1(Predicate & pred)204     unary_negate<Predicate> not1(Predicate &pred)
205     {
206         return unary_negate<Predicate>(pred);
207     }
208 
209     // --------------------------------------------------------------------------
210     // binary_negate, not2
211     // --------------------------------------------------------------------------
212     template <class Predicate>
213     class binary_negate
214         : public boost::functional::detail::binary_function<
215                                       typename binary_traits<Predicate>::first_argument_type,
216                                       typename binary_traits<Predicate>::second_argument_type,
217                                       bool>
218     {
219       public:
binary_negate(typename binary_traits<Predicate>::param_type x)220         explicit binary_negate(typename binary_traits<Predicate>::param_type x)
221             :
222             pred(x)
223         {}
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) const224         bool operator()(typename call_traits<typename binary_traits<Predicate>::first_argument_type>::param_type x,
225                         typename call_traits<typename binary_traits<Predicate>::second_argument_type>::param_type y) const
226         {
227             return !pred(x,y);
228         }
229       private:
230         typename binary_traits<Predicate>::function_type pred;
231     };
232 
233     template <class Predicate>
not2(const Predicate & pred)234     binary_negate<Predicate> not2(const Predicate &pred)
235     {
236         // The cast is to placate Borland C++Builder in certain circumstances.
237         // I don't think it should be necessary.
238         return binary_negate<Predicate>((typename binary_traits<Predicate>::param_type)pred);
239     }
240 
241     template <class Predicate>
not2(Predicate & pred)242     binary_negate<Predicate> not2(Predicate &pred)
243     {
244         return binary_negate<Predicate>(pred);
245     }
246 
247     // --------------------------------------------------------------------------
248     // binder1st, bind1st
249     // --------------------------------------------------------------------------
250     template <class Operation>
251     class binder1st
252         : public boost::functional::detail::unary_function<
253                                      typename binary_traits<Operation>::second_argument_type,
254                                      typename binary_traits<Operation>::result_type>
255     {
256       public:
binder1st(typename binary_traits<Operation>::param_type x,typename call_traits<typename binary_traits<Operation>::first_argument_type>::param_type y)257         binder1st(typename binary_traits<Operation>::param_type x,
258                   typename call_traits<typename binary_traits<Operation>::first_argument_type>::param_type y)
259             :
260             op(x), value(y)
261         {}
262 
263         typename binary_traits<Operation>::result_type
operator ()(typename call_traits<typename binary_traits<Operation>::second_argument_type>::param_type x) const264         operator()(typename call_traits<typename binary_traits<Operation>::second_argument_type>::param_type x) const
265         {
266             return op(value, x);
267         }
268 
269       protected:
270         typename binary_traits<Operation>::function_type op;
271         typename binary_traits<Operation>::first_argument_type value;
272     };
273 
274     template <class Operation>
bind1st(const Operation & op,typename call_traits<typename binary_traits<Operation>::first_argument_type>::param_type x)275     inline binder1st<Operation> bind1st(const Operation &op,
276                                         typename call_traits<
277                                                     typename binary_traits<Operation>::first_argument_type
278                                         >::param_type x)
279     {
280         // The cast is to placate Borland C++Builder in certain circumstances.
281         // I don't think it should be necessary.
282         return binder1st<Operation>((typename binary_traits<Operation>::param_type)op, x);
283     }
284 
285     template <class Operation>
bind1st(Operation & op,typename call_traits<typename binary_traits<Operation>::first_argument_type>::param_type x)286     inline binder1st<Operation> bind1st(Operation &op,
287                                         typename call_traits<
288                                                     typename binary_traits<Operation>::first_argument_type
289                                         >::param_type x)
290     {
291         return binder1st<Operation>(op, x);
292     }
293 
294     // --------------------------------------------------------------------------
295     // binder2nd, bind2nd
296     // --------------------------------------------------------------------------
297     template <class Operation>
298     class binder2nd
299         : public boost::functional::detail::unary_function<
300                                      typename binary_traits<Operation>::first_argument_type,
301                                      typename binary_traits<Operation>::result_type>
302     {
303       public:
binder2nd(typename binary_traits<Operation>::param_type x,typename call_traits<typename binary_traits<Operation>::second_argument_type>::param_type y)304         binder2nd(typename binary_traits<Operation>::param_type x,
305                   typename call_traits<typename binary_traits<Operation>::second_argument_type>::param_type y)
306             :
307             op(x), value(y)
308         {}
309 
310         typename binary_traits<Operation>::result_type
operator ()(typename call_traits<typename binary_traits<Operation>::first_argument_type>::param_type x) const311         operator()(typename call_traits<typename binary_traits<Operation>::first_argument_type>::param_type x) const
312         {
313             return op(x, value);
314         }
315 
316       protected:
317         typename binary_traits<Operation>::function_type op;
318         typename binary_traits<Operation>::second_argument_type value;
319     };
320 
321     template <class Operation>
bind2nd(const Operation & op,typename call_traits<typename binary_traits<Operation>::second_argument_type>::param_type x)322     inline binder2nd<Operation> bind2nd(const Operation &op,
323                                         typename call_traits<
324                                                     typename binary_traits<Operation>::second_argument_type
325                                         >::param_type x)
326     {
327         // The cast is to placate Borland C++Builder in certain circumstances.
328         // I don't think it should be necessary.
329         return binder2nd<Operation>((typename binary_traits<Operation>::param_type)op, x);
330     }
331 
332     template <class Operation>
bind2nd(Operation & op,typename call_traits<typename binary_traits<Operation>::second_argument_type>::param_type x)333     inline binder2nd<Operation> bind2nd(Operation &op,
334                                         typename call_traits<
335                                                     typename binary_traits<Operation>::second_argument_type
336                                         >::param_type x)
337     {
338         return binder2nd<Operation>(op, x);
339     }
340 
341     // --------------------------------------------------------------------------
342     // mem_fun, etc
343     // --------------------------------------------------------------------------
344     template <class S, class T>
345     class mem_fun_t : public boost::functional::detail::unary_function<T*, S>
346     {
347       public:
mem_fun_t(S (T::* p)())348         explicit mem_fun_t(S (T::*p)())
349             :
350             ptr(p)
351         {}
operator ()(T * p) const352         S operator()(T* p) const
353         {
354             return (p->*ptr)();
355         }
356       private:
357         S (T::*ptr)();
358     };
359 
360     template <class S, class T, class A>
361     class mem_fun1_t : public boost::functional::detail::binary_function<T*, A, S>
362     {
363       public:
mem_fun1_t(S (T::* p)(A))364         explicit mem_fun1_t(S (T::*p)(A))
365             :
366             ptr(p)
367         {}
operator ()(T * p,typename call_traits<A>::param_type x) const368         S operator()(T* p, typename call_traits<A>::param_type x) const
369         {
370             return (p->*ptr)(x);
371         }
372       private:
373         S (T::*ptr)(A);
374     };
375 
376     template <class S, class T>
377     class const_mem_fun_t : public boost::functional::detail::unary_function<const T*, S>
378     {
379       public:
const_mem_fun_t(S (T::* p)()const)380         explicit const_mem_fun_t(S (T::*p)() const)
381             :
382             ptr(p)
383         {}
operator ()(const T * p) const384         S operator()(const T* p) const
385         {
386             return (p->*ptr)();
387         }
388       private:
389         S (T::*ptr)() const;
390     };
391 
392     template <class S, class T, class A>
393     class const_mem_fun1_t : public boost::functional::detail::binary_function<const T*, A, S>
394     {
395       public:
const_mem_fun1_t(S (T::* p)(A)const)396         explicit const_mem_fun1_t(S (T::*p)(A) const)
397             :
398             ptr(p)
399         {}
operator ()(const T * p,typename call_traits<A>::param_type x) const400         S operator()(const T* p, typename call_traits<A>::param_type x) const
401         {
402             return (p->*ptr)(x);
403         }
404       private:
405         S (T::*ptr)(A) const;
406     };
407 
408     template<class S, class T>
mem_fun(S (T::* f)())409     inline mem_fun_t<S,T> mem_fun(S (T::*f)())
410     {
411         return mem_fun_t<S,T>(f);
412     }
413 
414     template<class S, class T, class A>
mem_fun(S (T::* f)(A))415     inline mem_fun1_t<S,T,A> mem_fun(S (T::*f)(A))
416     {
417         return mem_fun1_t<S,T,A>(f);
418     }
419 
420 #ifndef BOOST_NO_POINTER_TO_MEMBER_CONST
421     template<class S, class T>
mem_fun(S (T::* f)()const)422     inline const_mem_fun_t<S,T> mem_fun(S (T::*f)() const)
423     {
424         return const_mem_fun_t<S,T>(f);
425     }
426 
427     template<class S, class T, class A>
mem_fun(S (T::* f)(A)const)428     inline const_mem_fun1_t<S,T,A> mem_fun(S (T::*f)(A) const)
429     {
430         return const_mem_fun1_t<S,T,A>(f);
431     }
432 #endif // BOOST_NO_POINTER_TO_MEMBER_CONST
433 
434     // --------------------------------------------------------------------------
435     // mem_fun_ref, etc
436     // --------------------------------------------------------------------------
437     template <class S, class T>
438     class mem_fun_ref_t : public boost::functional::detail::unary_function<T&, S>
439     {
440       public:
mem_fun_ref_t(S (T::* p)())441         explicit mem_fun_ref_t(S (T::*p)())
442             :
443             ptr(p)
444         {}
operator ()(T & p) const445         S operator()(T& p) const
446         {
447             return (p.*ptr)();
448         }
449       private:
450         S (T::*ptr)();
451     };
452 
453     template <class S, class T, class A>
454     class mem_fun1_ref_t : public boost::functional::detail::binary_function<T&, A, S>
455     {
456       public:
mem_fun1_ref_t(S (T::* p)(A))457         explicit mem_fun1_ref_t(S (T::*p)(A))
458             :
459             ptr(p)
460         {}
operator ()(T & p,typename call_traits<A>::param_type x) const461         S operator()(T& p, typename call_traits<A>::param_type x) const
462         {
463             return (p.*ptr)(x);
464         }
465       private:
466         S (T::*ptr)(A);
467     };
468 
469     template <class S, class T>
470     class const_mem_fun_ref_t : public boost::functional::detail::unary_function<const T&, S>
471     {
472       public:
const_mem_fun_ref_t(S (T::* p)()const)473         explicit const_mem_fun_ref_t(S (T::*p)() const)
474             :
475             ptr(p)
476         {}
477 
operator ()(const T & p) const478         S operator()(const T &p) const
479         {
480             return (p.*ptr)();
481         }
482       private:
483         S (T::*ptr)() const;
484     };
485 
486     template <class S, class T, class A>
487     class const_mem_fun1_ref_t : public boost::functional::detail::binary_function<const T&, A, S>
488     {
489       public:
const_mem_fun1_ref_t(S (T::* p)(A)const)490         explicit const_mem_fun1_ref_t(S (T::*p)(A) const)
491             :
492             ptr(p)
493         {}
494 
operator ()(const T & p,typename call_traits<A>::param_type x) const495         S operator()(const T& p, typename call_traits<A>::param_type x) const
496         {
497             return (p.*ptr)(x);
498         }
499       private:
500         S (T::*ptr)(A) const;
501     };
502 
503     template<class S, class T>
mem_fun_ref(S (T::* f)())504     inline mem_fun_ref_t<S,T> mem_fun_ref(S (T::*f)())
505     {
506         return mem_fun_ref_t<S,T>(f);
507     }
508 
509     template<class S, class T, class A>
mem_fun_ref(S (T::* f)(A))510     inline mem_fun1_ref_t<S,T,A> mem_fun_ref(S (T::*f)(A))
511     {
512         return mem_fun1_ref_t<S,T,A>(f);
513     }
514 
515 #ifndef BOOST_NO_POINTER_TO_MEMBER_CONST
516     template<class S, class T>
mem_fun_ref(S (T::* f)()const)517     inline const_mem_fun_ref_t<S,T> mem_fun_ref(S (T::*f)() const)
518     {
519         return const_mem_fun_ref_t<S,T>(f);
520     }
521 
522     template<class S, class T, class A>
mem_fun_ref(S (T::* f)(A)const)523     inline const_mem_fun1_ref_t<S,T,A> mem_fun_ref(S (T::*f)(A) const)
524     {
525         return const_mem_fun1_ref_t<S,T,A>(f);
526     }
527 #endif // BOOST_NO_POINTER_TO_MEMBER_CONST
528 
529     // --------------------------------------------------------------------------
530     // ptr_fun
531     // --------------------------------------------------------------------------
532     template <class Arg, class Result>
533     class pointer_to_unary_function : public boost::functional::detail::unary_function<Arg,Result>
534     {
535       public:
pointer_to_unary_function(Result (* f)(Arg))536         explicit pointer_to_unary_function(Result (*f)(Arg))
537             :
538             func(f)
539         {}
540 
operator ()(typename call_traits<Arg>::param_type x) const541         Result operator()(typename call_traits<Arg>::param_type x) const
542         {
543             return func(x);
544         }
545 
546       private:
547         Result (*func)(Arg);
548     };
549 
550     template <class Arg, class Result>
ptr_fun(Result (* f)(Arg))551     inline pointer_to_unary_function<Arg,Result> ptr_fun(Result (*f)(Arg))
552     {
553         return pointer_to_unary_function<Arg,Result>(f);
554     }
555 
556     template <class Arg1, class Arg2, class Result>
557     class pointer_to_binary_function : public boost::functional::detail::binary_function<Arg1,Arg2,Result>
558     {
559       public:
pointer_to_binary_function(Result (* f)(Arg1,Arg2))560         explicit pointer_to_binary_function(Result (*f)(Arg1, Arg2))
561             :
562             func(f)
563         {}
564 
operator ()(typename call_traits<Arg1>::param_type x,typename call_traits<Arg2>::param_type y) const565         Result operator()(typename call_traits<Arg1>::param_type x, typename call_traits<Arg2>::param_type y) const
566         {
567             return func(x,y);
568         }
569 
570       private:
571         Result (*func)(Arg1, Arg2);
572     };
573 
574     template <class Arg1, class Arg2, class Result>
ptr_fun(Result (* f)(Arg1,Arg2))575     inline pointer_to_binary_function<Arg1,Arg2,Result> ptr_fun(Result (*f)(Arg1, Arg2))
576     {
577         return pointer_to_binary_function<Arg1,Arg2,Result>(f);
578     }
579 } // namespace boost
580 
581 #endif
582