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
19namespace 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:
183 explicit unary_negate(typename unary_traits<Predicate>::param_type x)
184 :
185 pred(x)
186 {}
187 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>
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>
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:
220 explicit binary_negate(typename binary_traits<Predicate>::param_type x)
221 :
222 pred(x)
223 {}
224 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>
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>
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:
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
264 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>
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>
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:
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
311 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>
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>
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:
348 explicit mem_fun_t(S (T::*p)())
349 :
350 ptr(p)
351 {}
352 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:
364 explicit mem_fun1_t(S (T::*p)(A))
365 :
366 ptr(p)
367 {}
368 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:
380 explicit const_mem_fun_t(S (T::*p)() const)
381 :
382 ptr(p)
383 {}
384 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:
396 explicit const_mem_fun1_t(S (T::*p)(A) const)
397 :
398 ptr(p)
399 {}
400 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>
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>
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>
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>
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:
441 explicit mem_fun_ref_t(S (T::*p)())
442 :
443 ptr(p)
444 {}
445 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:
457 explicit mem_fun1_ref_t(S (T::*p)(A))
458 :
459 ptr(p)
460 {}
461 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:
473 explicit const_mem_fun_ref_t(S (T::*p)() const)
474 :
475 ptr(p)
476 {}
477
478 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:
490 explicit const_mem_fun1_ref_t(S (T::*p)(A) const)
491 :
492 ptr(p)
493 {}
494
495 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>
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>
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>
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>
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:
536 explicit pointer_to_unary_function(Result (*f)(Arg))
537 :
538 func(f)
539 {}
540
541 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>
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:
560 explicit pointer_to_binary_function(Result (*f)(Arg1, Arg2))
561 :
562 func(f)
563 {}
564
565 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>
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

source code of include/boost/functional.hpp