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: |
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 | |